tizen 2.4 release accepted/tizen_2.4_mobile tizen_2.4 accepted/tizen/2.4/mobile/20151029.031822 submit/tizen_2.4/20151028.064644 tizen_2.4_mobile_release
authorjk7744.park <jk7744.park@samsung.com>
Sat, 24 Oct 2015 08:04:56 +0000 (17:04 +0900)
committerjk7744.park <jk7744.park@samsung.com>
Sat, 24 Oct 2015 08:04:56 +0000 (17:04 +0900)
31 files changed:
CMakeLists.txt [new file with mode: 0644]
Makefile [deleted file]
packaging/sdbd.changes
packaging/sdbd.spec
packaging/sdbd_device.service
packaging/sdbd_emulator.service
script/profile_command
script/sdk_launch
sdbd.manifest
src/commandline.c
src/file_sync_client.c
src/file_sync_service.c
src/mutex_list.h
src/properties.c
src/qemu_pipe.h
src/sdb.c
src/sdb.h
src/sdbd_plugin.h [new file with mode: 0644]
src/sdktools.c
src/sdktools.h
src/services.c
src/socket_loopback_client.c
src/socket_network_client.c
src/sockets.c
src/sysdeps.h
src/transport.c
src/transport_local.c
src/usb_linux.c
src/usb_linux_client.c
src/utils.c
src/utils.h

diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644 (file)
index 0000000..0611d4f
--- /dev/null
@@ -0,0 +1,98 @@
+# Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+#
+#    Licensed under the Apache License, Version 2.0 (the "License");
+#    you may not use this file except in compliance with the License.
+#    You may obtain a copy of the License at
+#
+#        http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS,
+#    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#    See the License for the specific language governing permissions and
+#    limitations under the License.
+#
+# @file        CMakeLists.txt
+# @author
+# @brief
+#
+
+############################# Check minimum CMake version #####################
+
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+PROJECT(sdbd)
+
+############################# cmake packages ##################################
+
+INCLUDE(FindPkgConfig)
+
+############################# compiler flags ##################################
+
+SET(SDBD_SRCS
+       src/sdb.c
+       src/fdevent.c
+       src/transport.c
+       src/transport_local.c
+       src/transport_usb.c
+       src/sockets.c
+       src/services.c
+       src/file_sync_service.c
+       src/usb_linux_client.c
+       src/utils.c
+       src/socket_inaddr_any_server.c
+       src/socket_local_client.c
+       src/socket_local_server.c
+       src/socket_loopback_client.c
+       src/socket_loopback_server.c
+       src/socket_network_client.c
+       src/sdktools.c
+       src/strutils.c
+       src/fileutils.c
+       )
+       
+pkg_check_modules(pkgs REQUIRED
+    capi-system-info
+    vconf
+    vasum
+    glib-2.0
+    dbus-1
+    dbus-glib-1
+    security-server
+ )
+FOREACH(flag ${pkgs_CFLAGS})
+        SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
+ENDFOREACH(flag)
+
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}")
+
+INCLUDE_DIRECTORIES(src)
+
+ADD_DEFINITIONS("-O2 -g -Wall -Wno-unused-parameter -fPIE")
+ADD_DEFINITIONS("-DSDB_HOST=0")
+ADD_DEFINITIONS("-D_XOPEN_SOURCE")
+ADD_DEFINITIONS("-D_GNU_SOURCE")
+ADD_DEFINITIONS("-DHAVE_FORKEXEC")
+ADD_DEFINITIONS("-D_DROP_PRIVILEGE")
+ADD_DEFINITIONS("-D_FILE_OFFSET_BITS=64")
+
+IF (_ARM_TARGET)
+    ADD_DEFINITIONS("-DANDROID_GADGET=1")
+ENDIF (_ARM_TARGET)
+
+IF(TARGET_ARCH STREQUAL x86)
+    ADD_DEFINITIONS("-DTARGET_ARCH_X86")
+ELSE()
+    ADD_DEFINITIONS("-DTARGET_ARCH_ARM")
+ENDIF()
+
+IF(WEARABLE_PROFILE STREQUAL on)
+    ADD_DEFINITIONS("-D_WEARABLE")
+ENDIF()
+
+find_package(Threads REQUIRED)
+
+ADD_EXECUTABLE(sdbd ${SDBD_SRCS})
+TARGET_LINK_LIBRARIES(sdbd -pie -lsmack -lresolv -ldl ${CMAKE_THREAD_LIBS_INIT} ${pkgs_LDFLAGS})
+
+install(TARGETS sdbd DESTINATION /usr/sbin)
diff --git a/Makefile b/Makefile
deleted file mode 100644 (file)
index 3e48fd7..0000000
--- a/Makefile
+++ /dev/null
@@ -1,73 +0,0 @@
-#
-#
-# Makefile for sdbd
-#
-
-#
-HOST_OS := $(shell uname -s | tr A-Z a-z)
-
-# sdb host tool
-# =========================================================
-
-SDBD_SRC_FILES := \
-       src/sdb.c \
-       src/fdevent.c \
-       src/transport.c \
-       src/transport_local.c \
-       src/transport_usb.c \
-       src/sockets.c \
-       src/services.c \
-       src/file_sync_service.c \
-       src/usb_linux_client.c \
-       src/utils.c \
-       src/socket_inaddr_any_server.c \
-       src/socket_local_client.c \
-       src/socket_local_server.c \
-       src/socket_loopback_client.c \
-       src/socket_loopback_server.c \
-       src/socket_network_client.c \
-       src/sdktools.c \
-       src/strutils.c \
-       src/fileutils.c
-
-SDBD_CFLAGS := -O2 -g -DSDB_HOST=0 -Wall -Wno-unused-parameter
-SDBD_CFLAGS += -D_XOPEN_SOURCE -D_GNU_SOURCE
-SDBD_CFLAGS += -DHAVE_FORKEXEC -fPIE -D_DROP_PRIVILEGE -D_FILE_OFFSET_BITS=64
-SDBD_LFLAGS := -lcapi-system-info -lvconf -lsmack
-IFLAGS := -Iinclude -Isrc -I/usr/include/system -I/usr/include/vconf
-OBJDIR := bin
-INSTALLDIR := usr/sbin
-
-UNAME := $(shell uname -sm)
-ifneq (,$(findstring 86,$(UNAME)))
-       HOST_ARCH := x86
-endif
-
-TARGET_ARCH = $(HOST_ARCH)
-ifeq ($(TARGET_ARCH),)
-       TARGET_ARCH := arm
-endif
-
-ifeq ($(TARGET_ARCH),arm)
-       MODULE := sdbd
-       SDBD_CFLAGS += -DANDROID_GADGET=1
-else
-ifeq ($(TARGET_HOST),true)
-       MODULE := sdb
-else
-       MODULE := sdbd
-endif
-endif
-
-all : $(MODULE)
-
-sdbd : $(SDBD_SRC_FILES)
-       mkdir -p $(OBJDIR)
-       $(CC) -pthread -o $(OBJDIR)/$(MODULE) $(SDBD_CFLAGS) $(IFLAGS) $(SDBD_SRC_FILES) $(SDBD_LFLAGS)
-
-install :
-       mkdir -p $(DESTDIR)/$(INSTALLDIR)
-       install $(OBJDIR)/$(MODULE) $(DESTDIR)/$(INSTALLDIR)/$(MODULE)
-
-clean :
-       rm -rf $(OBJDIR)/*
index abe5d97..394e8d4 100644 (file)
@@ -1,6 +1,3 @@
-* Thu Nov 27 2014 Sanghoon Hong <sanghoon.hong@samsung.com>
- - added a notify thread for emulator detection
- - fixed a broken connection issue while 'pull'ing files
 * Wed Nov 27 2013 Yoonki Park <yoonki.park@samsung.com>
  - changed port redirection to usb0 instead of loopback
 * Wed Apr 04 2013 Ho Namkoong <ho.namkoong@samsung.com>
index ef4e34a..3e327fd 100644 (file)
@@ -1,5 +1,5 @@
 Name:       sdbd
-Version:    2.2.23
+Version:    2.2.32
 Release:    1
 License:    Apache-2.0
 Summary:    SDB daemon
@@ -8,13 +8,21 @@ Source0:    %{name}-%{version}.tar.gz
 Source1001:    sdbd_device.service
 Source1002:    sdbd_emulator.service
 
-BuildRequires: capi-system-info-devel
-BuildRequires: vconf-devel
-BuildRequires: smack-devel
+BuildRequires: cmake
+#BuildRequires: sec-product-features
+BuildRequires: pkgconfig(libsmack)
+BuildRequires: pkgconfig(capi-system-info)
+BuildRequires: pkgconfig(vconf)
+BuildRequires: pkgconfig(vasum)
+BuildRequires: pkgconfig(glib-2.0)
+BuildRequires: pkgconfig(dbus-1)
+BuildRequires: pkgconfig(dbus-glib-1)
+BuildRequires: pkgconfig(security-server)
 Requires: default-files-tizen
 Requires: sys-assert
 Requires: debug-launchpad
 Requires: dbus
+Requires: security-server
 
 %description
 Description: SDB daemon.
@@ -23,6 +31,20 @@ Description: SDB daemon.
 %setup -q
 
 %build
+%if "%{?tizen_profile_name}" == "wearable"
+%define wearable_profile on
+%else
+%define wearable_profile off
+%endif
+%ifarch %{ix86}
+%define target_arch x86
+%else
+%define target_arch arm
+%endif
+cmake . -DCMAKE_INSTALL_PREFIX=%{_prefix} \
+       -DWEARABLE_PROFILE=%{wearable_profile} \
+       -DTARGET_ARCH=%{target_arch}
+
 make %{?jobs:-j%jobs}
 
 %install
@@ -35,9 +57,6 @@ mkdir -p %{buildroot}%{_libdir}/systemd/system
 install -m 0644 %SOURCE1002 %{buildroot}%{_libdir}/systemd/system/sdbd.service
 mkdir -p %{buildroot}/%{_libdir}/systemd/system/emulator.target.wants
 ln -s %{_libdir}/systemd/system/sdbd.service %{buildroot}/%{_libdir}/systemd/system/emulator.target.wants/
-mkdir -p %{buildroot}%{_sysconfdir}/systemd/default-extra-dependencies/ignore-units.d/
-ln -s %{_libdir}/systemd/system/sdbd.service %{buildroot}%{_sysconfdir}/systemd/default-extra-dependencies/ignore-units.d/
-
 %else
 install -m 0644 %SOURCE1001 %{buildroot}%{_libdir}/systemd/system/sdbd.service
 %endif
@@ -60,10 +79,39 @@ chsmack -t /home/developer
 %{_libdir}/systemd/system/sdbd.service
 %ifarch %{ix86}
 %{_libdir}/systemd/system/emulator.target.wants/sdbd.service
-%{_sysconfdir}/systemd/default-extra-dependencies/ignore-units.d/sdbd.service
 %endif
 /usr/share/license/%{name}
 /usr/bin/profile_command
 
 %changelog
+* Thu Jul 13 2015 - Shingil Kang <shingil.kang@samsung.com>
+- Supported 'boot' protocol to get status of platform booting
+- Add new protocol "capability" to get the platform capability information
+
+* Thu Jun 15 2015 - Shingil Kang <shingil.kang@samsung.com>
+- Added to network smack rule for emulator guest IP (10.0.2.15)
+- Removed to create sdb_port.txt file
+
+* Thu Jun 8 2015 - Shingil Kang <shingil.kang@samsung.com>
+- Used CMake
+
+* Thu Jun 2 2015 - Shingil Kang <shingil.kang@samsung.com>
+- Added to ask sdb server to connect emulator with bridged network.
+
+* Thu May 23 2015 - Shingil Kang <shingil.kang@samsung.com>
+- notify_sdbd_startup_thread() added.
+
+* Thu May 21 2015 - Shingil Kang <shingil.kang@samsung.com>
+- Removed systemd dependency of zone
+- Set default dependency off
+- Removed requires(post) condition
+
+* Mon Apr 30 2015 - Shingil Kang <shingil.kang@samsung.com>
+- Fix a bug for sdb 'push' into /opt, /var, /root, /home in foreground zone shell mode
+- Change to apply connection mode (zone/host/denied) in boot time
+
+* Mon Apr 21 2015 - Shingil Kang <shingil.kang@samsung.com>
+- Execute debug-launchpad when zone is started
 
+* Mon Apr 18 2015 - Shingil Kang <shingil.kang@samsung.com>
+- Change "sdb forward" command to be zone-aware
index 1570a3d..9af3d02 100644 (file)
@@ -1,5 +1,6 @@
 [Unit]
 Description=sdbd
+After=tmp.mount
 
 [Service]
 Type=forking
index fde66ac..80d31b6 100644 (file)
@@ -1,12 +1,14 @@
 [Unit]
 Description=sdbd
+After=tmp.mount dbus.service
+#DefaultDependencies=false
 
 [Service]
 Type=forking
 Environment=DISPLAY=:0
 PIDFile=/tmp/.sdbd.pid
 RemainAfterExit=yes
-ExecStartPre=/bin/bash -c "/bin/echo `/bin/sed 's/^.*sdb_port=\([^, ]*\).*$/\1/g' /proc/cmdline` > /opt/home/sdb_port.txt"
+ExecStartPre=/bin/bash -c "/bin/echo '10.0.2.15/32 system::debugging_network' >> /smack/netlabel"
 ExecStart=/usr/sbin/sdbd
 
 [Install]
index ce52681..cdaef64 100755 (executable)
@@ -1,24 +1,22 @@
 #!/bin/bash
 
-VERSION="3.0"
+VERSION="4.0"
 KILL=/usr/bin/killall
 MANAGER=/usr/bin/da_manager
 FIND=/usr/bin/find
 GETAPPINSTALLPATH="/usr/bin/pkgcmd -a"
 PORTFILE=/tmp/port.da
-READLINK=/usr/bin/readlink
 
 print_usage()
 {
        echo "usage: profile_command [options]"
        echo "Options:"
-       echo "getprobemap               get da_api_map"
-       echo "killmanager               terminate da_manager"
-       echo "runmanager                execute da_manager"
-       echo "findunittest              find unittest project"
+       echo "getprobemap               get da_api_map"
+       echo "killmanager               terminate da_manager"
+       echo "runmanager                execute da_manager"
+       echo "findunittest              find unittest project"
        echo "getversion                get version"
        echo "killvalgrind              kill valgrind process"
-       echo "readlink filepath         get value of given symbolic link or canonical file name"
 }
 
 get_probe_map()
@@ -45,7 +43,7 @@ find_unittest()
 
 process_list()
 {
-       /bin/ps -eo pid,cmd
+       /bin/ps -ewo pid,cmd
 }
 
 get_version()
@@ -53,33 +51,16 @@ get_version()
        echo $VERSION
 }
 
-read_link()
-{
-       $READLINK -f $FILEPATH
-}
-
 kill_valgrind()
 {
         /bin/ps ax | /bin/grep "/home/developer/sdk_tools/valgrind/usr/bin/valgrin[d]" | /usr/bin/awk '{print "kill -3 " $1}' | /bin/sh
 }
 
-if test $# -gt 2 -o $# -lt 1; then
+if test $# -ne 1 ; then
        print_usage
        exit 1
 fi
 
-if test -n "$2"; then
-       case "$1" in
-               readlink)
-                       FILEPATH=$2
-                       ;;
-               *)
-                       print_usage
-                       exit 1
-                       ;;
-       esac
-fi
-
 case "$1" in
        killmanager)
                kill_manager
@@ -96,15 +77,12 @@ case "$1" in
        getversion)
                get_version
                ;;
-       readlink)
-               read_link
-               ;;
        killvalgrind)
-                kill_valgrind
-                ;;
-        getprobemap)
-                get_probe_map
-                ;;
+               kill_valgrind
+               ;;
+       getprobemap)
+               get_probe_map
+               ;;
        *)
                echo "Unknown option!"
                print_usage
index 5537feb..5b300a5 100755 (executable)
@@ -131,7 +131,7 @@ then
     if [ "" != "$attach_id" ]
     #debug attach
     then
-        cmd="$COV_TEST_PREFIX /home/developer/sdk_tools/gdbserver/gdbserver :$port --attach $attach_id"
+        cmd="/usr/bin/launch_debug $launch_app_arg1 __AUL_SDK__ ATTACH __DLP_ATTACH_ARG__ --attach,:$port,$attach_id"
     #debug
     else
         if [ "" != "$result_mode" ]
index 02b5aed..1effc20 100644 (file)
             <smack request="system::debugging_network" type="w" />
             <smack request="device::input" type="rwx" />
             <smack request="*" type="rwxat" />
+            <smack request="tizen::vconf::platform::rw" type="r" />
+            <smack request="tizen::vconf::public::r::platform::rw" type="r" />
+            <smack request="tizen::vconf::setting::admin" type="r" />
+            <smack request="procps" type="rx" />
+            <smack request="security-server::label" type="w" />
         </request>
         <permit>
             <smack permit="system::use_internet" type="w" />
@@ -30,6 +35,9 @@
             <smack permit="wrt::wrt-launcher" type="rw" />
         </permit>
     </define>
+    <assign>
+        <filesystem path="/usr/lib/*" label="_" exec_label="none"/>
+    </assign>
     <request>
         <domain name="sdbd" />
     </request>
index 7b6f7a9..fe3e796 100644 (file)
@@ -801,7 +801,7 @@ static const char *find_product_out_path(const char *hint)
      */
     if (sdb_dirstart(hint) != NULL) {
         if (getcwd(path_buf, sizeof(path_buf)) == NULL) {
-            fprintf(stderr, "sdb: Couldn't get CWD: %s\n", strerror(errno));
+            fprintf(stderr, "sdb: Couldn't get CWD: errno:%d\n", errno);
             return NULL;
         }
         if (strlen(path_buf) + 1 + strlen(hint) >= sizeof(path_buf)) {
index 0e80efd..3ba3770 100644 (file)
@@ -216,7 +216,7 @@ static int write_data_file(int fd, const char *path, syncsendbuf *sbuf)
 
     lfd = sdb_open(path, O_RDONLY);
     if(lfd < 0) {
-        fprintf(stderr,"cannot open '%s': %s\n", path, strerror(errno));
+        fprintf(stderr,"cannot open '%s': errno:%d\n", path, errno);
         return -1;
     }
 
@@ -231,7 +231,7 @@ static int write_data_file(int fd, const char *path, syncsendbuf *sbuf)
         if(ret < 0) {
             if(errno == EINTR)
                 continue;
-            fprintf(stderr,"cannot read '%s': %s\n", path, strerror(errno));
+            fprintf(stderr,"cannot read '%s': errno:%d\n", path, errno);
             break;
         }
 
@@ -279,7 +279,7 @@ static int write_data_link(int fd, const char *path, syncsendbuf *sbuf)
 
     len = readlink(path, sbuf->data, SYNC_DATA_MAX-1);
     if(len < 0) {
-        fprintf(stderr, "error reading link '%s': %s\n", path, strerror(errno));
+        fprintf(stderr, "error reading link '%s': errno:%d\n", path, errno);
         return -1;
     }
     sbuf->data[len] = '\0';
@@ -324,7 +324,7 @@ static int sync_send(int fd, const char *lpath, const char *rpath,
         // this requires that we read the entire file into memory.
         lfd = sdb_open(lpath, O_RDONLY);
         if(lfd < 0) {
-            fprintf(stderr,"cannot open '%s': %s\n", lpath, strerror(errno));
+            fprintf(stderr,"cannot open '%s': errno:%d\n", lpath, errno);
             return -1;
         }
 
@@ -469,7 +469,7 @@ int sync_recv(int fd, const char *rpath, const char *lpath)
         mkdirs((char *)lpath);
         lfd = sdb_creat(lpath, 0644);
         if(lfd < 0) {
-            fprintf(stderr,"cannot create '%s': %s\n", lpath, strerror(errno));
+            fprintf(stderr,"cannot create '%s': errno:%d\n", lpath, errno);
             return -1;
         }
         goto handle_data;
@@ -499,7 +499,7 @@ int sync_recv(int fd, const char *rpath, const char *lpath)
         }
 
         if(writex(lfd, buffer, len)) {
-            fprintf(stderr,"cannot write '%s': %s\n", rpath, strerror(errno));
+            fprintf(stderr,"cannot write '%s': errno:%d\n", rpath, errno);
             sdb_close(lfd);
             return -1;
         }
@@ -614,7 +614,7 @@ static int local_build_list(copyinfo **filelist,
 
     d = opendir(lpath);
     if(d == 0) {
-        fprintf(stderr,"cannot open '%s': %s\n", lpath, strerror(errno));
+        fprintf(stderr,"cannot open '%s': errno:%d\n", lpath, errno);
         return -1;
     }
 
@@ -644,7 +644,7 @@ static int local_build_list(copyinfo **filelist,
         } else {
             ci = mkcopyinfo(lpath, rpath, name, 0);
             if(lstat(ci->src, &st)) {
-                fprintf(stderr,"cannot stat '%s': %s\n", ci->src, strerror(errno));
+                fprintf(stderr,"cannot stat '%s': errno:%d\n", ci->src, errno);
                 closedir(d);
 
                 return -1;
@@ -758,7 +758,7 @@ int do_sync_push(const char *lpath, const char *rpath, int verifyApk, int isUtf8
     }
 
     if(stat(lpath, &st)) {
-        fprintf(stderr,"cannot stat '%s': %s\n", lpath, strerror(errno));
+        fprintf(stderr,"cannot stat '%s': errno:%d\n", lpath, errno);
         sync_quit(fd);
         return 1;
     }
index bd953d8..d95a667 100644 (file)
 #include <sys/socket.h>
 #include <sys/select.h>
 #include <sys/smack.h>
+#include <security-server.h>
 #include "sysdeps.h"
 
 #define TRACE_TAG  TRACE_SYNC
 #include "sdb.h"
+#include "sdbd_plugin.h"
 #include "file_sync_service.h"
 #include "sdktools.h"
 #include "utils.h"
 
 #define SYNC_TIMEOUT 15
 
-struct sync_permit_rule
-{
-    const char *name;
-    const char *regx;
-    int mode; // 0:push, 1: pull, 2: push&push
-};
-
-struct sync_permit_rule sdk_sync_permit_rule[] = {
-//    /* 0 */ {"rds", "^((/opt/apps)|(/opt/usr/apps))/[a-zA-Z0-9]{10}/info/\\.sdk_delta\\.info$", 1},
-    /* 1 */ {"unitest", "^((/tmp)|(/opt/apps)|(/opt/usr/apps))/[a-zA-Z0-9]{10}/data/[a-zA-Z0-9_\\-]{1,50}\\.xml$", 1},
-    /* 2 */ {"codecoverage", "^((/tmp)|(/opt/apps)|(/opt/usr/apps))/[a-zA-Z0-9]{10}/data/+(.)*\\.gcda$", 1},
-    /* 3 */ {"da", "^(/tmp/da/)*+[a-zA-Z0-9_\\-\\.]{1,50}\\.png$", 1},
-    /* end */ {NULL, NULL, 0}
-};
-
 /* The typical default value for the umask is S_IWGRP | S_IWOTH (octal 022).
  * Before use the DIR_PERMISSION, the process umask value should be set 0 using umask().
  */
 #define DIR_PERMISSION 0777
 
-int is_install_pkg_file = 0;
-
 static void set_syncfile_smack_label(char *src) {
     char *label_transmuted = NULL;
     char *label = NULL;
@@ -66,11 +51,6 @@ static void set_syncfile_smack_label(char *src) {
     int pos = src_chr - src + 1;
     char dirname[512];
 
-    if (getuid() != 0) {
-        D("need root permission to set smack label: %d\n", getuid());
-        return;
-    }
-
     snprintf(dirname, pos, "%s", src);
 
     //D("src:[%s], dirname:[%s]\n", src, dirname);
@@ -80,8 +60,9 @@ static void set_syncfile_smack_label(char *src) {
         if (!strcmp("TRUE", label_transmuted)) {
             rc = smack_getlabel(dirname, &label, SMACK_LABEL_ACCESS);
             if (rc == 0 && label != NULL) {
-                if (smack_setlabel(src, label, SMACK_LABEL_ACCESS) == -1) {
-                    D("unable to set sync file smack label %s due to %s\n", label, strerror(errno));
+                rc = security_server_label_access(src, label);
+                if (rc != SECURITY_SERVER_API_SUCCESS) {
+                    D("unable to set sync file smack label %s due to %d\n", label, errno);
                 }
                 free(label);
             }
@@ -90,8 +71,9 @@ static void set_syncfile_smack_label(char *src) {
         }
         free(label_transmuted);
     } else {
-        if (smack_setlabel(src, SMACK_SYNC_FILE_LABEL, SMACK_LABEL_ACCESS) == -1) {
-            D("unable to set sync file smack label %s due to (errno:%d)\n", SMACK_SYNC_FILE_LABEL, errno);
+        rc = security_server_label_access(src, SMACK_SYNC_FILE_LABEL);
+        if (rc != SECURITY_SERVER_API_SUCCESS) {
+            D("unable to set sync file smack label %s due to %d\n", SMACK_SYNC_FILE_LABEL, errno);
         }
     }
 }
@@ -108,12 +90,12 @@ static int sync_send_label_notify(int s, const char *path, int success)
 
 static void sync_read_label_notify(int s)
 {
-    char buffer[512] = {0,};
+    char buffer[512 + 1] = {0,};
 
     while (1) {
-        int len = sdb_read(s, buffer, sizeof(buffer));
+        int len = sdb_read(s, buffer, sizeof(buffer) - 1);
         if (len < 0) {
-            D("sync notify read error : (errno:%d)\n", errno);
+            D("sync notify read errno:%d\n", errno);
             exit(-1);
         }
 
@@ -121,7 +103,7 @@ static void sync_read_label_notify(int s)
             D("sync notify child process exit\n");
             exit(-1);
         }
-        buffer[511] = '\0';
+        buffer[len] = '\0';
         char *path = buffer;
         path++;
         path++;
@@ -150,7 +132,7 @@ static int mkdirs(int noti_fd, char *name)
             sync_send_label_notify(noti_fd, name, 1);
         }
         if((ret < 0) && (errno != EEXIST)) {
-            D("mkdir(\"%s\") -> (errno:%d)\n", name, errno);
+            D("mkdir(\"%s\") -> errno:%d\n", name, errno);
             *x = '/';
             return ret;
         }
@@ -171,7 +153,7 @@ static int do_stat(int s, const char *path)
         msg.stat.mode = 0;
         msg.stat.size = 0;
         msg.stat.time = 0;
-        D("failed to stat %s due to: (errno:%d)\n", path, errno);
+        D("failed to stat %s due to: errno:%d\n", path, errno);
     } else {
         msg.stat.mode = htoll(st.st_mode);
         msg.stat.size = htoll(st.st_size);
@@ -192,6 +174,9 @@ static int do_list(int s, const char *path)
     char tmp[1024 + 256 + 1];
     char *fname;
 
+    char dirent_buffer[ sizeof(struct dirent) + 260 + 1 ]  = {0,};
+    struct dirent *dirent_r = (struct dirent*)dirent_buffer;
+
     len = strlen(path);
     memcpy(tmp, path, len);
     tmp[len] = '/';
@@ -201,11 +186,11 @@ static int do_list(int s, const char *path)
 
     d = opendir(path);
     if(d == NULL) {
-        D("failed to open dir due to: (errno:%d)\n", errno);
+        D("failed to open dir due to: errno:%d\n", errno);
         goto done;
     }
 
-    while((de = readdir(d))) {
+    while((readdir_r(d, dirent_r, &de) == 0) && de) {
         int len = strlen(de->d_name);
 
             /* not supposed to be possible, but
@@ -259,37 +244,73 @@ static int fail_message(int s, const char *reason)
 
 static int fail_errno(int s)
 {
-       char err_msg[20] = {0, };
-       snprintf(err_msg, sizeof(err_msg), "(errno:%d)", errno);
-    return fail_message(s, err_msg);
+       char buf[512];
+
+       strerror_r(s, buf, sizeof(buf));
+
+    return fail_message(s, buf);
 }
 
 // FIXME: should get the following paths with api later but, do it for simple and not having dependency on other packages
+#define VAR_ABS_PATH        "/opt/var"
+#define VSM_ZONE_PATH       "/var/lib/lxc/"
+#define VSM_ZONE_ROOTFS     "rootfs/"
 #define CMD_MEDIADB_UPDATE "/usr/bin/mediadb-update"
 #define MEDIA_CONTENTS_PATH1 "/opt/media"
 #define MEDIA_CONTENTS_PATH2 "/opt/usr/media"
 #define MEDIA_CONTENTS_PATH3 "/opt/storage/sdcard"
 
 static void sync_mediadb(char *path) {
+       int is_inzone = 0;
+
     if (access(CMD_MEDIADB_UPDATE, F_OK) != 0) {
         D("%s: command not found\n", CMD_MEDIADB_UPDATE);
         return;
     }
 
-    if (strstr(path, MEDIA_CONTENTS_PATH1) != NULL) {
-        char *arg_list[] = {CMD_MEDIADB_UPDATE, "r", MEDIA_CONTENTS_PATH1, NULL};
+    if (strstr(path, VAR_ABS_PATH) == path) {
+        path += 4;
+    }
+    if (strstr(path, VSM_ZONE_PATH) == path) {
+        path += sizeof(VSM_ZONE_PATH) - 1;
+        while (*(path++) != '/');
+        while (*(path++) == '/');
+        path--;
 
-        spawn(CMD_MEDIADB_UPDATE, arg_list);
-        D("media db update done to %s\n", MEDIA_CONTENTS_PATH1);
-    } else if (strstr(path, MEDIA_CONTENTS_PATH2) != NULL) {
-        char *arg_list[] = {CMD_MEDIADB_UPDATE, "r", MEDIA_CONTENTS_PATH2, NULL};
+               if (strstr(path, VSM_ZONE_ROOTFS) == path) {
+                       path += sizeof(VSM_ZONE_ROOTFS) - 1;
+                       while (*(path++) == '/');
+                       path -= 2;
+                       is_inzone = 1;
+        }
+     }
 
-        spawn(CMD_MEDIADB_UPDATE, arg_list);
+    if (strstr(path, MEDIA_CONTENTS_PATH1) != NULL) {
+       if (is_inzone) {
+           char *arg_list[] = {CMD_ATTACH, "-f", "--", CMD_MEDIADB_UPDATE, "-r", MEDIA_CONTENTS_PATH1, NULL};
+           spawn(CMD_ATTACH, arg_list);
+       } else {
+           char *arg_list[] = {CMD_MEDIADB_UPDATE, "-r", MEDIA_CONTENTS_PATH1, NULL};
+            spawn(CMD_MEDIADB_UPDATE, arg_list);
+            D("media db update done to %s\n", MEDIA_CONTENTS_PATH1);
+       }
+    } else if (strstr(path, MEDIA_CONTENTS_PATH2) != NULL) {
+       if (is_inzone) {
+           char *arg_list[] = {CMD_ATTACH, "-f", "--", CMD_MEDIADB_UPDATE, "-r", MEDIA_CONTENTS_PATH2, NULL};
+           spawn(CMD_ATTACH, arg_list);
+       } else {
+           char *arg_list[] = {CMD_MEDIADB_UPDATE, "-r", MEDIA_CONTENTS_PATH2, NULL};
+           spawn(CMD_MEDIADB_UPDATE, arg_list);
+       }
         D("media db update done to %s\n", MEDIA_CONTENTS_PATH2);
     } else if (strstr(path, MEDIA_CONTENTS_PATH3) != NULL) {
-        char *arg_list[] = {CMD_MEDIADB_UPDATE, "r", MEDIA_CONTENTS_PATH3, NULL};
-
-        spawn(CMD_MEDIADB_UPDATE, arg_list);
+       if (is_inzone) {
+           char *arg_list[] = {CMD_ATTACH, "-f", "--", CMD_MEDIADB_UPDATE, "-r", MEDIA_CONTENTS_PATH3, NULL};
+           spawn(CMD_ATTACH, arg_list);
+       } else {
+           char *arg_list[] = {CMD_MEDIADB_UPDATE, "-r", MEDIA_CONTENTS_PATH3, NULL};
+           spawn(CMD_MEDIADB_UPDATE, arg_list);
+       }
         D("media db update done to %s\n", MEDIA_CONTENTS_PATH3);
     }
     return;
@@ -429,12 +450,30 @@ static int handle_send_link(int s, int noti_fd, char *path, char *buffer)
 }
 #endif /* HAVE_SYMLINKS */
 
+static int is_support_push()
+{
+    return (!strncmp(g_capabilities.filesync_support, SDBD_CAP_RET_PUSHPULL, strlen(SDBD_CAP_RET_PUSHPULL))
+            || !strncmp(g_capabilities.filesync_support, SDBD_CAP_RET_PUSH, strlen(SDBD_CAP_RET_PUSH)));
+}
+
+static int is_support_pull()
+{
+    return (!strncmp(g_capabilities.filesync_support, SDBD_CAP_RET_PUSHPULL, strlen(SDBD_CAP_RET_PUSHPULL))
+            || !strncmp(g_capabilities.filesync_support, SDBD_CAP_RET_PULL, strlen(SDBD_CAP_RET_PULL)));
+}
+
 static int do_send(int s, int noti_fd, char *path, char *buffer)
 {
     char *tmp;
     mode_t mode;
     int is_link, ret;
 
+    // Check the capability for file push support.
+    if(!is_support_push()) {
+        fail_message(s, "NO support file push.");
+        return -1;
+    }
+
     tmp = strrchr(path,',');
     if(tmp) {
         *tmp = 0;
@@ -453,8 +492,8 @@ static int do_send(int s, int noti_fd, char *path, char *buffer)
         mode = 0644; // set default permission value in most of unix system.
         is_link = 0;
     }
-    if(is_install_pkg_file) {
-        mode = 0444;
+    if (is_pkg_file_path(path)) {
+        mode = 0644;
         is_link = 0;
     }
 
@@ -487,6 +526,12 @@ static int do_recv(int s, const char *path, char *buffer)
     syncmsg msg;
     int fd, r;
 
+    // Check the capability for file push support.
+    if (!is_support_pull()) {
+        fail_message(s, "NO support file pull.");
+        return -1;
+    }
+
     fd = sdb_open(path, O_RDONLY);
     if(fd < 0) {
         if(fail_errno(s)) return -1;
@@ -521,39 +566,27 @@ static int do_recv(int s, const char *path, char *buffer)
     return 0;
 }
 
-static int verify_sync_rule(const char* path) {
-    regex_t regex;
-    int ret;
-    char buf[PATH_MAX];
-    int i=0;
+static pid_t get_zone_init_pid(const char *name) {
+    char filename[PATH_MAX];
+    FILE *fp;
+    pid_t ret = -1;
 
-    // to prevent hijacking the pkg file.
-    if (is_pkg_file_path(path)) {
-        is_install_pkg_file = 1;
-        D("matched pkg file path: to prevent hijacking the pkg file\n");
-        return 1;
-    }
+    snprintf(filename, sizeof(filename),
+            "/sys/fs/cgroup/devices/lxc/%s/cgroup.procs", name);
 
-    for (i=0; sdk_sync_permit_rule[i].regx != NULL; i++) {
-        ret = regcomp(&regex, sdk_sync_permit_rule[i].regx, REG_EXTENDED);
-        if(ret){
-            return 0;
-        }
-        // execute regular expression
-        ret = regexec(&regex, path, 0, NULL, 0);
-        if(!ret){
-            regfree(&regex);
-            D("found matched rule(%s) from %s path\n", sdk_sync_permit_rule[i].name, path);
-            return 1;
-        } else if( ret == REG_NOMATCH ){
-            // do nothin
-        } else{
-            regerror(ret, &regex, buf, sizeof(buf));
-            D("regex match failed(%s): %s\n",sdk_sync_permit_rule[i].name, buf);
+    fp = fopen(filename, "r");
+
+    if (fp != NULL) {
+        if (fscanf(fp, "%d", &ret) < 0) {
+            D("Failed to read %s\n", filename);
+            ret = -2;
         }
+        fclose(fp);
+    } else {
+        D("Unable to access %s\n", filename);
+        ret = errno;
     }
-    regfree(&regex);
-    return 0;
+    return ret;
 }
 
 void file_sync_service(int fd, void *cookie)
@@ -565,7 +598,8 @@ void file_sync_service(int fd, void *cookie)
     struct timeval timeout;
     int rv;
     int s[2];
-    is_install_pkg_file = 0;
+    char zone_path[1025] = {0, };
+    char name_vsm[1025] = {0, };
 
     if(sdb_socketpair(s)) {
         D("cannot create service socket pair\n");
@@ -579,6 +613,9 @@ void file_sync_service(int fd, void *cookie)
     FD_ZERO(&set); /* clear the set */
     FD_SET(fd, &set); /* add our file descriptor to the set */
 
+    timeout.tv_sec = SYNC_TIMEOUT;
+    timeout.tv_usec = 0;
+
     pid_t pid = fork();
 
     if (pid == 0) {
@@ -586,13 +623,31 @@ void file_sync_service(int fd, void *cookie)
         sync_read_label_notify(s[1]);
     } else if (pid > 0) {
         sdb_close(s[1]);
+
+        if (hostshell_mode == 0) {
+            FILE *fp;
+            fp = popen("/usr/bin/vsm-foreground", "r");
+            if (fp == NULL) {
+                D("Failed to create pipe of vsm-foreground\n");
+                goto fail;
+            }
+            fgets(name_vsm, 1025, fp);
+            pclose(fp);
+
+            //trim zone name
+            namelen = strlen(name_vsm);
+            while (name_vsm[--namelen] == '\n')
+                ;
+            name_vsm[namelen + 1] = '\0';
+            snprintf(zone_path, 1025, "/proc/%d/root",
+                    get_zone_init_pid(name_vsm));
+            chroot(zone_path);
+            chdir("/");
+        }
+
         for(;;) {
             D("sync: waiting for command for %d sec\n", SYNC_TIMEOUT);
 
-            // in Linux, timeout would be altered after each select() call.
-            // Therefore, re-initialization is needed.
-            timeout.tv_sec = SYNC_TIMEOUT;
-            timeout.tv_usec = 0;
             rv = select(fd + 1, &set, NULL, NULL, &timeout);
             if (rv == -1) {
                 D("sync file descriptor select failed\n");
@@ -620,7 +675,7 @@ void file_sync_service(int fd, void *cookie)
             msg.req.namelen = 0;
             D("sync: '%s' '%s'\n", (char*) &msg.req, name);
 
-            if (should_drop_privileges() && !verify_sync_rule(name)) {
+            if (should_drop_privileges()) {
                 set_developer_privileges();
             }
 
index 3e55e9f..1baea49 100644 (file)
@@ -24,6 +24,7 @@
 SDB_MUTEX(dns_lock)
 SDB_MUTEX(socket_list_lock)
 SDB_MUTEX(transport_lock)
+SDB_MUTEX(zone_check_lock);
 #if SDB_HOST
 SDB_MUTEX(local_transports_lock)
 #endif
index c187d30..65562fc 100644 (file)
@@ -237,8 +237,8 @@ static int connectToServer(const char* fileName)
     if (cc < 0) {
         // ENOENT means socket file doesn't exist
         // ECONNREFUSED means socket exists but nobody is listening
-        D("AF_UNIX connect failed for '%s': %s\n",
-            fileName, strerror(errno));
+        D("AF_UNIX connect failed for '%s': errno:%d\n",
+            fileName, errno);
         sdb_close(sock);
         return -1;
     }
index 5d6e87e..0cb5f93 100644 (file)
@@ -67,7 +67,7 @@ qemu_pipe_open(const char*  pipeName)
 
     fd = open("/dev/qemu_pipe", O_RDWR);
     if (fd < 0) {
-        D("%s: Could not open /dev/qemu_pipe: %s", __FUNCTION__, strerror(errno));
+        D("%s: Could not open /dev/qemu_pipe: errno:%d", __FUNCTION__, errno);
         //errno = ENOSYS;
         return -1;
     }
@@ -76,7 +76,7 @@ qemu_pipe_open(const char*  pipeName)
 
     ret = TEMP_FAILURE_RETRY(write(fd, buff, buffLen+1));
     if (ret != buffLen+1) {
-        D("%s: Could not connect to %s pipe service: %s", __FUNCTION__, pipeName, strerror(errno));
+        D("%s: Could not connect to %s pipe service: errno:%d", __FUNCTION__, pipeName, errno);
         if (ret == 0) {
             errno = ECONNRESET;
         } else if (ret > 0) {
index 072f05b..f8d8ed8 100644 (file)
--- a/src/sdb.c
+++ b/src/sdb.c
 #include <signal.h>
 #include <grp.h>
 #include <pthread.h>
+#include <dlfcn.h>
 
 #include "sysdeps.h"
 #include "sdb.h"
 #include "strutils.h"
 #include "utils.h"
+#include "sdktools.h"
 
 #if !SDB_HOST
 #include <linux/prctl.h>
 #else
 #include "usb_vendors.h"
 #endif
-#include <system_info_internal.h>
+#include <system_info.h>
 #include <vconf.h>
 #include "utils.h"
-
 #define PROC_CMDLINE_PATH "/proc/cmdline"
 #define USB_SERIAL_PATH "/sys/class/usb_mode/usb0/iSerial"
 
+#include <sys/ioctl.h>
+#include <net/if.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#define GUEST_IP_INTERFACE "eth0"
+
+SDB_MUTEX_DEFINE(zone_check_lock);
 #if SDB_TRACE
 SDB_MUTEX_DEFINE( D_lock );
 #endif
 
 int HOST = 0;
+int initial_zone_mode_check = 0;
+
+void* g_sdbd_plugin_handle = NULL;
+SDBD_PLUGIN_CMD_PROC_PTR sdbd_plugin_cmd_proc = NULL;
 
 int is_emulator(void) {
-    if (access(USB_NODE_FILE, F_OK) == 0) {
+/* XXX: If the target device supports x86 architecture,
+ *      this routine is INVALID. */
+#ifdef TARGET_ARCH_X86
+    return 1;
+#else
+    return 0;
+#endif
+}
+
+int is_container_enabled(void) {
+       bool value;
+       int ret;
+       ret = system_info_get_platform_bool("tizen.org/feature/container", &value);
+       if (ret != SYSTEM_INFO_ERROR_NONE) {
+               D("failed to get container information: %d\n", errno);
+               return 0;
+       } else {
+               D("tizen container: %d\n", value);
+               if (value == true)
+                       return 1;
+               else
+                       return 0;
+       }
+}
+
+int has_container(void) {
+    FILE *fp;
+    char name_vsm[1025] = {0, };
+    char empty_vsm[1025] = {0, };
+    fp = popen(CMD_LIST, "r");
+    if(fp == NULL) {
+        D("Failed to create pipe of %s \n", CMD_LIST);
         return 0;
-    } else {
+    }
+    fgets(name_vsm, 1025, fp);
+    pclose(fp);
+
+    D("zone list :%s\n", name_vsm);
+    // check zone list
+    if((name_vsm[0] == '\n')  || !strncmp(name_vsm, empty_vsm, 1025))
+        return 0;
+    else
         return 1;
+}
+
+char** get_zone_list() {
+    FILE *fp;
+    char name_vsm[1025] = {0, };
+    char empty_vsm[1025] = {0, };
+    fp = popen(CMD_LIST, "r");
+    if(fp == NULL) {
+        D("Failed to create pipe of %s \n", CMD_LIST);
+        return 0;
+    }
+    fgets(name_vsm, 1025, fp);
+    pclose(fp);
+
+    D("zone list :%s\n", name_vsm);
+
+    if((name_vsm[0] == '\n')  || !strncmp(name_vsm, empty_vsm, 1025))
+        return NULL;
+    else {
+        char** tokens = str_split(name_vsm, '\n');
+        return tokens;
     }
 }
 
@@ -66,19 +138,6 @@ void handle_sig_term(int sig) {
         sdb_unlink(SDB_PIDPATH);
 #endif
     char *cmd1_args[] = {"/usr/bin/killall", "/usr/bin/debug_launchpad_preloading_preinitializing_daemon", NULL};
-
-    if (!is_emulator()) {
-        int val = 0;
-        if (vconf_get_int(DEBUG_MODE_KEY, &val)) {
-            D("Failed to get debug mode\n");
-        } else {
-            if (usb_mode != 6 && val == 6) { // set mtp mode by default!.
-                vconf_set_int(DEBUG_MODE_KEY, 2);
-            }
-        }
-    } else {
-        // do nothing on a emulator
-    }
     spawn("/usr/bin/killall", cmd1_args);
     sdb_sleep_ms(1000);
 }
@@ -100,7 +159,7 @@ void fatal_errno(const char *fmt, ...)
 {
     va_list ap;
     va_start(ap, fmt);
-    fprintf(stderr, "error: (errno:%d): ", errno);
+    fprintf(stderr, "errno: %d: ", errno);
     vfprintf(stderr, fmt, ap);
     fprintf(stderr, "\n");
     va_end(ap);
@@ -435,10 +494,9 @@ int get_emulator_forward_port() {
     return port;
 }
 
-int get_emulator_name(char str[], int str_size) {
+static int get_cmdline_value(char *split, char str[], int str_size) {
     char cmdline[512];
     int fd = unix_open(PROC_CMDLINE_PATH, O_RDONLY);
-    char *name_str = "vm_name=";
 
     if (fd < 0) {
         D("fail to read /proc/cmdline\n");
@@ -446,8 +504,8 @@ int get_emulator_name(char str[], int str_size) {
     }
     if(read_line(fd, cmdline, sizeof(cmdline))) {
         D("qemu cmd: %s\n", cmdline);
-        if (get_str_cmdline(cmdline, name_str, str, str_size) < 1) {
-            D("could not get emulator name from cmdline\n");
+        if (get_str_cmdline(cmdline, split, str, str_size) < 1) {
+            D("could not get the (%s) value from cmdline\n", split);
             sdb_close(fd);
             return -1;
         }
@@ -456,9 +514,13 @@ int get_emulator_name(char str[], int str_size) {
     return 0;
 }
 
+int get_emulator_name(char str[], int str_size) {
+    return get_cmdline_value("vm_name=", str, str_size);
+}
+
 int get_device_name(char str[], int str_size) {
     char *value = NULL;
-    int r = system_info_get_value_string(SYSTEM_INFO_KEY_MODEL, &value);
+    int r = system_info_get_platform_string("http://tizen.org/system/model_name", &value);
     if (r != SYSTEM_INFO_ERROR_NONE) {
         D("fail to get system model:%d\n", errno);
         return -1;
@@ -487,6 +549,40 @@ int get_device_name(char str[], int str_size) {
     return -1;
 }
 
+int get_emulator_hostip(char str[], int str_size) {
+    return get_cmdline_value("host_ip=", str, str_size);
+}
+
+int get_emulator_guestip(char str[], int str_size) {
+    int           s;
+    struct ifreq ifr;
+    struct sockaddr_in *sin;
+
+    s = socket(AF_INET, SOCK_DGRAM, 0);
+    if(s < 0) {
+        D("socket error\n");
+        return -1;
+    }
+
+    snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "%s", GUEST_IP_INTERFACE);
+    if(ioctl(s, SIOCGIFHWADDR, &ifr) < 0) {
+        D("ioctl hwaddr error\n");
+        sdb_close(s);
+        return -1;
+    }
+
+    if(ioctl(s, SIOCGIFADDR, &ifr) < 0) {
+        D("ioctl addr error\n");
+        sdb_close(s);
+        return -1;
+    }
+    sin = (struct sockaddr_in *)&ifr.ifr_addr;
+    snprintf(str, str_size, "%s", inet_ntoa(sin->sin_addr));
+    sdb_close(s);
+
+    return 0;
+}
+
 void parse_banner(char *banner, atransport *t)
 {
     char *type, *product, *end;
@@ -581,6 +677,9 @@ void handle_packet(apacket *p, atransport *t)
         if (is_pwlocked() && t->connection_state == CS_PWLOCK) { // in case of already locked before get A_CNXN
             D("open failed due to password locked before get A_CNXN:%d\n", t->connection_state);
             send_close(0, p->msg.arg0, t);
+        } else if (hostshell_mode == 2){
+            D("open failed due to denied mode\n");
+            send_close(0, p->msg.arg0, t);
         } else {
             if(t->connection_state != CS_OFFLINE) {
                 char *name = (char*) p->data;
@@ -658,9 +757,7 @@ static void ss_listener_event_func(int _fd, unsigned ev, void *_l)
         fd = sdb_socket_accept(_fd, &addr, &alen);
         if(fd < 0) return;
 
-        if (sdb_socket_setbufsize(fd, CHUNK_SIZE) == -1) {
-            D("failed to set buffer size of sdb socket: (errno:%d)\n", errno);
-        }
+        sdb_socket_setbufsize(fd, CHUNK_SIZE);
 
         s = create_local_socket(fd);
         if(s) {
@@ -856,6 +953,10 @@ static BOOL WINAPI ctrlc_handler(DWORD type)
 
 static void sdb_cleanup(void)
 {
+    if (g_sdbd_plugin_handle) {
+        dlclose(g_sdbd_plugin_handle);
+        g_sdbd_plugin_handle = NULL;
+    }
     usb_cleanup();
 }
 
@@ -1150,15 +1251,29 @@ int is_pwlocked(void) {
         pwlock_status = 0;
         D("failed to get pw lock status\n");
     }
+#ifdef _WEARABLE
+    D("wearable lock applied\n");
+    // for wearable which uses different VCONF key (lock type)
+       if (vconf_get_int(VCONFKEY_SETAPPL_PRIVACY_LOCK_TYPE_INT, &pwlock_type)) {
+               pwlock_type = 0;
+               D("failed to get pw lock type\n");
+       }
+         if ((pwlock_status == VCONFKEY_IDLE_LOCK) && (pwlock_type != SETTING_PRIVACY_LOCK_TYPE_NONE)) {
+                  D("device has been locked\n");
+                  return 1; // locked!
+         }
+#else
+       D("mobile lock applied\n");
+    // for mobile
     if (vconf_get_int(VCONFKEY_SETAPPL_SCREEN_LOCK_TYPE_INT, &pwlock_type)) {
         pwlock_type = 0;
         D("failed to get pw lock type\n");
     }
-    if (pwlock_status == VCONFKEY_IDLE_LOCK && (pwlock_type == SETTING_SCREEN_LOCK_TYPE_SIMPLE_PASSWORD || pwlock_type == SETTING_SCREEN_LOCK_TYPE_PASSWORD)) {
+    if (pwlock_status == VCONFKEY_IDLE_LOCK && ((pwlock_type != SETTING_SCREEN_LOCK_TYPE_NONE) && (pwlock_type != SETTING_SCREEN_LOCK_TYPE_SWIPE))) {
         D("device has been locked\n");
         return 1; // locked!
     }
-
+#endif
     return 0; // unlocked!
 }
 
@@ -1196,15 +1311,107 @@ void register_pwlock_cb() {
     }
 }
 
+#include <dbus/dbus.h>
+#include <dbus/dbus-glib.h>
+#include <dbus/dbus-glib-lowlevel.h>
+
+#define BOOTING_DONE_SIGNAL    "BootingDone"
+#define DEVICED_CORE_INTERFACE "org.tizen.system.deviced.core"
+#define SDBD_BOOT_INFO_FILE "/tmp/sdbd_boot_info"
+
+static DBusHandlerResult __sdbd_dbus_signal_filter(DBusConnection *conn,
+               DBusMessage *message, void *user_data) {
+       D("got dbus message\n");
+       const char *interface;
+
+       DBusError error;
+       dbus_error_init(&error);
+
+       interface = dbus_message_get_interface(message);
+       if (interface == NULL) {
+               D("reject by security issue - no interface\n");
+               return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+       }
+
+       if (dbus_message_is_signal(message, DEVICED_CORE_INTERFACE,
+                       BOOTING_DONE_SIGNAL)) {
+               booting_done = 1;
+               if (access(SDBD_BOOT_INFO_FILE, F_OK) == 0) {
+                       D("booting is done before\n");
+               } else {
+                       FILE *f = fopen(SDBD_BOOT_INFO_FILE, "w");
+                       if (f != NULL) {
+                               fprintf(f, "%d", 1);
+                               fclose(f);
+                       }
+               }
+               D("booting is done\n");
+       }
+
+       D("handled dbus message\n");
+       return DBUS_HANDLER_RESULT_HANDLED;
+}
+
+static void *bootdone_cb(void *x) {
+       int MAX_LOCAL_BUFSZ = 128;
+       DBusError error;
+       DBusConnection *bus;
+       char rule[MAX_LOCAL_BUFSZ];
+       GMainLoop *mainloop;
+
+       g_type_init();
+
+       dbus_error_init(&error);
+       bus = dbus_bus_get(DBUS_BUS_SYSTEM, &error);
+       if (!bus) {
+               D("Failed to connect to the D-BUS daemon: %s", error.message);
+               dbus_error_free(&error);
+               return -1;
+       }
+       dbus_connection_setup_with_g_main(bus, NULL);
+
+       snprintf(rule, MAX_LOCAL_BUFSZ, "type='signal',interface='%s'",
+                       DEVICED_CORE_INTERFACE);
+       /* listening to messages */
+       dbus_bus_add_match(bus, rule, &error);
+       if (dbus_error_is_set(&error)) {
+               D("Fail to rule set: %s", error.message);
+               dbus_error_free(&error);
+               return -1;
+       }
+
+       if (dbus_connection_add_filter(bus, __sdbd_dbus_signal_filter, NULL, NULL)
+                       == FALSE)
+               return -1;
+
+       D("booting signal initialized\n");
+       mainloop = g_main_loop_new(NULL, FALSE);
+       g_main_loop_run(mainloop);
+
+       D("dbus loop exited");
+
+       return 0;
+}
+
+void register_bootdone_cb() {
+       D("registerd bootdone callback\n");
+
+       sdb_thread_t t;
+       if (sdb_thread_create(&t, bootdone_cb, NULL)) {
+               D("cannot create service thread\n");
+               return;
+       }
+}
+
 int set_developer_privileges() {
     gid_t groups[] = { SID_DEVELOPER, SID_APP_LOGGING, SID_SYS_LOGGING, SID_INPUT };
     if (setgroups(sizeof(groups) / sizeof(groups[0]), groups) != 0) {
-        D("set groups failed (errno: %d, %s)\n", errno, strerror(errno));
+        D("set groups failed (errno: %d)\n", errno);
     }
 
     // then switch user and group to developer
     if (setgid(SID_DEVELOPER) != 0) {
-        D("set group id failed (errno: %d, %s)\n", errno, strerror(errno));
+        D("set group id failed (errno: %d)\n", errno);
         return -1;
     }
 
@@ -1221,7 +1428,7 @@ int set_developer_privileges() {
         }
     }
     // TODO: use pam later
-    putenv("HOME=/home/developer");
+    setenv("HOME", "/home/developer", 1);
 
     return 1;
 }
@@ -1233,32 +1440,620 @@ static void execute_required_process() {
     spawn("/usr/bin/debug_launchpad_preloading_preinitializing_daemon", cmd_args);
 }
 
-static void init_sdk_requirements() {
-    struct stat st;
+#include <stdio.h>
+#include <glib.h>
+#include <vasum.h>
+
+static const char *const state_string[] = {
+       "STOPPED",
+       "STARTING",
+       "RUNNING",
+       "STOPPING",
+       "ABORTING",
+       "FREEZING",
+       "THAWED",
+};
+
+static const char *const event_string[] = {
+       "NONE",
+       "CREATED",
+       "DESTROYED",
+       "SWITCHED",
+};
+
+static void execute_required_process_in_each_zone(char* zone_name) {
+       D("Name of zone which executes required processes : %s \n", zone_name);
+
+       // debug-launchpad need to be executed in each zone
+       char zone_name_with_option[100] = {0,};
+       snprintf(zone_name_with_option, sizeof(zone_name_with_option), "--name=%s", zone_name);
+       char *arg_list[] = {CMD_ATTACH, zone_name_with_option, "--", "/usr/bin/debug_launchpad_preloading_preinitializing_daemon", NULL};
+       spawn(CMD_ATTACH, arg_list);
+}
+
+static int vasum_zone_state_cb( vsm_zone_h zone, vsm_zone_state_t state, void * userdata)
+{
+       char * zone_name;
+       vsm_zone_state_t before_state, new_state;
+
+       zone_name = vsm_get_zone_name(zone);
+       before_state = vsm_get_zone_state(zone);
+       new_state = state;
+
+       D("Zone state is changed : Name[%s] , Before State[%s], Changed State[%s]\n",
+                       zone_name , state_string[state], state_string[state]);
+
+
+       if(state == 2) {
+               sdb_mutex_lock(&zone_check_lock);
+               // if state of zone is "RUNNING", execute required process in zone.
+               execute_required_process_in_each_zone(zone_name);
+
+               // in the case sdbd is started up before zone, check zone/host mode
+               if(!initial_zone_mode_check) {
+                       D("set zone mode on when zone is started up\n");
+                       initial_zone_mode_check = 1;
+                       hostshell_mode = 0;
+               }
+               sdb_mutex_unlock(&zone_check_lock);
+       }
+
+
+       return 0;
+}
+
+static int vasum_event_cb( vsm_zone_h zone, vsm_zone_event_t event, void * userdata)
+{
+       char * zone_name;
+
+       zone_name = vsm_get_zone_name(zone);
+
+       D("Zone got event : Name[%s], Event[%s]\n", zone_name, event_string[event]);
+
+       return 0;
+}
+
+static gboolean vasum_context_callback(GIOChannel * channel, GIOCondition condition,
+               void *data)
+{
+       vsm_context_h ctx = (vsm_context_h)data;
+       /* Call handler function for update vsm_context */
+       vsm_enter_eventloop(ctx, 0, 0);
+       return TRUE;
+}
+
+
+static void *zone_check_thread(void *x) {
+       GMainLoop *mainloop;
+       vsm_context_h ctx;
+       int fd, ret;
+       int state_hndl = 0;
+       int event_hndl = 0;
+
+       mainloop = g_main_loop_new(NULL, FALSE);
+
+       int i;
+       for(i = 0; i < 10; i++) {
+               D("Try to get vasum context : try %d\n", i);
+               ctx = vsm_create_context();
+               if (ctx != NULL) {
+                       D("Got vasum context\n");
+                       break;
+               }
+               if(i == 9) {
+                       D("Failed to get vasum context, exit vasum zone check thread\n");
+                       return;
+               }
+               D("Failed get vasum context\n");
+               sdb_sleep_ms(100);
+       }
+
+       /* Get vasum event file descriptor from vsm context */
+       fd = vsm_get_poll_fd(ctx);
+       if (fd < 0) {
+               D("Failed to get poll fd\n");
+       }
+
+       GIOChannel *channel = g_io_channel_unix_new(fd);
+       if (channel == NULL) {
+               D("Failed to allocate channel allocation\n");
+               return;
+       }
+
+       /* Bind vasum context to g_main_loop watch handler */
+       g_io_add_watch(channel, G_IO_IN, vasum_context_callback, ctx);
+
+       state_hndl = vsm_add_state_changed_callback(ctx, vasum_zone_state_cb, (void *) ctx);
+       if (state_hndl < 0) {
+               D("Failed to register state changed cb\n");
+               return -1;
+       }
+
+       event_hndl = vsm_add_event_callback(ctx, vasum_event_cb, (void *) ctx);
+       if (event_hndl < 0) {
+               D("Failed to register event cb\n");
+               return -1;
+       }
+
+       g_main_loop_run(mainloop);
+
+       ret = vsm_del_state_changed_callback(ctx, state_hndl);
+       if (ret != VSM_ERROR_NONE) {
+               D("Failed to deregister state changed callback\n");
+       }
+
+       ret = vsm_del_event_callback(ctx, event_hndl);
+       if (ret != VSM_ERROR_NONE) {
+               D("Failed to deregister event callback\n");
+       }
+
+       /* Cleanup context in vsm_context */
+       vsm_cleanup_context(ctx);
+
+       return 0;
+}
+
+static void create_zone_check_thread() {
+       sdb_thread_t t;
+       if (sdb_thread_create(&t, zone_check_thread, NULL)) {
+               D("cannot create_zone_check_thread.\n");
+               return;
+       }
+       D("created zone_check_thread\n");
+}
+
+/* default plugin proc */
+static int get_plugin_capability(const char* in_buf, sdbd_plugin_param out) {
+    int ret = SDBD_PLUGIN_RET_NOT_SUPPORT;
+
+    if (in_buf == NULL) {
+        D("Invalid argument\n");
+        return SDBD_PLUGIN_RET_FAIL;
+    }
+
+    if (SDBD_CMP_CAP(in_buf, SECURE)) {
+        snprintf(out.data, out.len, "%s", SDBD_CAP_RET_DISABLED);
+        ret = SDBD_PLUGIN_RET_SUCCESS;
+    } else if (SDBD_CMP_CAP(in_buf, INTER_SHELL)) {
+        snprintf(out.data, out.len, "%s", SDBD_CAP_RET_ENABLED);
+        ret = SDBD_PLUGIN_RET_SUCCESS;
+    } else if (SDBD_CMP_CAP(in_buf, FILESYNC)) {
+        // - push : SDBD_CAP_RET_PUSH
+        // - pull : SDBD_CAP_RET_PULL
+        // - both : SDBD_CAP_RET_PUSHPULL
+        // - disabled : SDBD_CAP_RET_DISABLED
+        snprintf(out.data, out.len, "%s", SDBD_CAP_RET_PUSHPULL);
+        ret = SDBD_PLUGIN_RET_SUCCESS;
+    } else if (SDBD_CMP_CAP(in_buf, USBPROTO)) {
+        if (is_emulator()) {
+            snprintf(out.data, out.len, "%s", SDBD_CAP_RET_DISABLED);
+        } else {
+            snprintf(out.data, out.len, "%s", SDBD_CAP_RET_ENABLED);
+        }
+        ret = SDBD_PLUGIN_RET_SUCCESS;
+    } else if (SDBD_CMP_CAP(in_buf, SOCKPROTO)) {
+        if (is_emulator()) {
+            snprintf(out.data, out.len, "%s", SDBD_CAP_RET_ENABLED);
+        } else {
+            snprintf(out.data, out.len, "%s", SDBD_CAP_RET_DISABLED);
+        }
+        ret = SDBD_PLUGIN_RET_SUCCESS;
+    } else if (SDBD_CMP_CAP(in_buf, ROOTONOFF)) {
+        if (access("/bin/su", F_OK) == 0) {
+            snprintf(out.data, out.len, "%s", SDBD_CAP_RET_ENABLED);
+        } else {
+            snprintf(out.data, out.len, "%s", SDBD_CAP_RET_DISABLED);
+        }
+    } else if (SDBD_CMP_CAP(in_buf, PLUGIN_VER)) {
+        snprintf(out.data, out.len, "%s", UNKNOWN);
+        ret = SDBD_PLUGIN_RET_SUCCESS;
+    } else if (SDBD_CMP_CAP(in_buf, PRODUCT_VER)) {
+        snprintf(out.data, out.len, "%s", UNKNOWN);
+        ret = SDBD_PLUGIN_RET_SUCCESS;
+    }
+
+    return ret;
+}
+
+static int verify_shell_cmd(const char* in_buf, sdbd_plugin_param out) {
+    int ret = SDBD_PLUGIN_RET_FAIL;
+
+    if (in_buf == NULL) {
+        D("Invalid argument\n");
+        return SDBD_PLUGIN_RET_FAIL;
+    }
+
+    D("shell command : %s\n", in_buf);
+
+    snprintf(out.data, out.len, "%s", SDBD_RET_VALID);
+    ret = SDBD_PLUGIN_RET_SUCCESS;
+
+    return ret;
+}
+
+static int convert_shell_cmd(const char* in_buf, sdbd_plugin_param out) {
+    int ret = SDBD_PLUGIN_RET_FAIL;
+
+    if (in_buf == NULL) {
+        D("Invalid argument\n");
+        return SDBD_PLUGIN_RET_FAIL;
+    }
+
+    snprintf(out.data, out.len, "%s", in_buf);
+    ret = SDBD_PLUGIN_RET_SUCCESS;
+
+    return ret;
+}
+
+static int verify_peer_ip(const char* in_buf, sdbd_plugin_param out) {
+    int ret = SDBD_PLUGIN_RET_FAIL;
+
+    if (in_buf == NULL) {
+        D("Invalid argument\n");
+        return SDBD_PLUGIN_RET_FAIL;
+    }
+
+    D("peer ip : %s\n", in_buf);
+
+    snprintf(out.data, out.len, "%s", SDBD_RET_VALID);
+    ret = SDBD_PLUGIN_RET_SUCCESS;
+
+    return ret;
+}
+
+static int verify_sdbd_launch(const char* in_buf, sdbd_plugin_param out) {
+    snprintf(out.data, out.len, "%s", SDBD_RET_VALID);
+    return SDBD_PLUGIN_RET_SUCCESS;
+}
+
+static int verify_root_cmd(const char* in_buf, sdbd_plugin_param out) {
+    int ret = SDBD_PLUGIN_RET_FAIL;
+
+    if (in_buf == NULL) {
+        D("Invalid argument\n");
+        return SDBD_PLUGIN_RET_FAIL;
+    }
 
-    // initialize usb mode
-    usb_mode = 0;
+    D("shell command : %s\n", in_buf);
 
-    if (stat(ONDEMAND_ROOT_PATH, &st) == -1) {
+    if (verify_root_commands(in_buf)) {
+        snprintf(out.data, out.len, "%s", SDBD_RET_VALID);
+    } else {
+        snprintf(out.data, out.len, "%s", SDBD_RET_INVALID);
+    }
+    ret = SDBD_PLUGIN_RET_SUCCESS;
+
+    return ret;
+}
+
+int default_cmd_proc(const char* cmd,
+                    const char* in_buf, sdbd_plugin_param out) {
+    int ret = SDBD_PLUGIN_RET_NOT_SUPPORT;
+
+    /* Check the arguments */
+    if (cmd == NULL || out.data == NULL) {
+        D("Invalid argument\n");
+        return SDBD_PLUGIN_RET_FAIL;
+    }
+
+    D("handle the command : %s\n", cmd);
+
+    /* Handle the request from sdbd */
+    if (SDBD_CMP_CMD(cmd, PLUGIN_CAP)) {
+        ret = get_plugin_capability(in_buf, out);
+    } else if (SDBD_CMP_CMD(cmd, VERIFY_SHELLCMD)) {
+        ret = verify_shell_cmd(in_buf, out);
+    } else if (SDBD_CMP_CMD(cmd, CONV_SHELLCMD)) {
+        ret = convert_shell_cmd(in_buf, out);
+    } else if (SDBD_CMP_CMD(cmd, VERIFY_PEERIP)) {
+        ret = verify_peer_ip(in_buf, out);
+    } else if (SDBD_CMP_CMD(cmd, VERIFY_LAUNCH)) {
+        ret = verify_sdbd_launch(in_buf, out);
+    } else if (SDBD_CMP_CMD(cmd, VERIFY_ROOTCMD)) {
+        ret = verify_root_cmd(in_buf, out);
+    } else {
+        D("Not supported command : %s\n", cmd);
+        ret = SDBD_PLUGIN_RET_NOT_SUPPORT;
+    }
+
+    return ret;
+}
+
+int request_plugin_cmd(const char* cmd, const char* in_buf,
+                        char *out_buf, unsigned int out_len)
+{
+    int ret = SDBD_PLUGIN_RET_FAIL;
+    sdbd_plugin_param out;
+
+    if (out_len > SDBD_PLUGIN_OUTBUF_MAX) {
+        D("invalid parameter : %s\n", cmd);
+        return 0;
+    }
+
+    out.data = out_buf;
+    out.len = out_len;
+
+    ret = sdbd_plugin_cmd_proc(cmd, in_buf, out);
+    if (ret == SDBD_PLUGIN_RET_FAIL) {
+        D("failed to request : %s\n", cmd);
+        return 0;
+    }
+    if (ret == SDBD_PLUGIN_RET_NOT_SUPPORT) {
+        // retry in default handler
+        ret = default_cmd_proc(cmd, in_buf, out);
+        if (ret == SDBD_PLUGIN_RET_FAIL) {
+            D("failed to request : %s\n", cmd);
+            return 0;
+        }
+    }
+
+    // add null character.
+    out_buf[out_len-1] = '\0';
+    D("return value: %s\n", out_buf);
+
+    return 1;
+}
+
+static void load_sdbd_plugin() {
+    sdbd_plugin_cmd_proc = NULL;
+
+    g_sdbd_plugin_handle = dlopen(SDBD_PLUGIN_PATH, RTLD_NOW);
+    if (!g_sdbd_plugin_handle) {
+        D("failed to dlopen(%s). error: %s\n", SDBD_PLUGIN_PATH, dlerror());
+        sdbd_plugin_cmd_proc = default_cmd_proc;
         return;
     }
-    if (st.st_uid != SID_DEVELOPER || st.st_gid != SID_DEVELOPER) {
-        char *arg_list[] = {"/bin/chown", ONDEMAND_ROOT_PATH, "-R", NULL};
 
-        spawn("/bin/chown", arg_list);
+    sdbd_plugin_cmd_proc = dlsym(g_sdbd_plugin_handle, SDBD_PLUGIN_INTF);
+    if (!sdbd_plugin_cmd_proc) {
+        D("failed to get the sdbd plugin interface. error: %s\n", dlerror());
+        dlclose(g_sdbd_plugin_handle);
+        g_sdbd_plugin_handle = NULL;
+        sdbd_plugin_cmd_proc = default_cmd_proc;
+        return;
     }
 
+    D("using sdbd plugin interface.(%s)\n", SDBD_PLUGIN_PATH);
+}
+
+static void init_sdk_requirements() {
+    struct stat st;
+
     execute_required_process();
 
     register_pwlock_cb();
+
+    if (is_emulator()) {
+        register_bootdone_cb();
+    }
+}
+
+int request_plugin_verification(const char* cmd, const char* in_buf) {
+    char out_buf[32] = {0,};
+
+    if(!request_plugin_cmd(cmd, in_buf, out_buf, sizeof(out_buf))) {
+        D("failed to request plugin command. : %s\n", SDBD_CMD_VERIFY_LAUNCH);
+        return 0;
+    }
+
+    if (strlen(out_buf) == 7 && !strncmp(out_buf, SDBD_RET_INVALID, 7)) {
+        D("[%s] is NOT verified.\n", cmd);
+        return 0;
+    }
+
+    D("[%s] is verified.\n", cmd);
+    return 1;
+}
+
+static char* get_cpu_architecture()
+{
+    int ret = 0;
+    bool b_value = false;
+
+    ret = system_info_get_platform_bool(
+            "http://tizen.org/feature/platform.core.cpu.arch.armv6", &b_value);
+    if (ret == SYSTEM_INFO_ERROR_NONE && b_value) {
+        return CPUARCH_ARMV6;
+    }
+
+    ret = system_info_get_platform_bool(
+            "http://tizen.org/feature/platform.core.cpu.arch.armv7", &b_value);
+    if (ret == SYSTEM_INFO_ERROR_NONE && b_value) {
+        return CPUARCH_ARMV7;
+    }
+
+    ret = system_info_get_platform_bool(
+            "http://tizen.org/feature/platform.core.cpu.arch.x86", &b_value);
+    if (ret == SYSTEM_INFO_ERROR_NONE && b_value) {
+        return CPUARCH_X86;
+    }
+
+    D("fail to get the CPU architecture of model:%d\n", errno);
+    return UNKNOWN;
+}
+
+static void init_capabilities(void) {
+    int ret = -1;
+    char *value = NULL;
+
+    memset(&g_capabilities, 0, sizeof(g_capabilities));
+
+    // CPU Architecture of model
+    snprintf(g_capabilities.cpu_arch, sizeof(g_capabilities.cpu_arch),
+                "%s", get_cpu_architecture());
+
+
+    // Secure protocol support
+    if(!request_plugin_cmd(SDBD_CMD_PLUGIN_CAP, SDBD_CAP_TYPE_SECURE,
+                            g_capabilities.secure_protocol,
+                            sizeof(g_capabilities.secure_protocol))) {
+        D("failed to request. (%s:%s) \n", SDBD_CMD_PLUGIN_CAP, SDBD_CAP_TYPE_SECURE);
+        snprintf(g_capabilities.secure_protocol, sizeof(g_capabilities.secure_protocol),
+                    "%s", DISABLED);
+    }
+
+
+    // Interactive shell support
+    if(!request_plugin_cmd(SDBD_CMD_PLUGIN_CAP, SDBD_CAP_TYPE_INTER_SHELL,
+                            g_capabilities.intershell_support,
+                            sizeof(g_capabilities.intershell_support))) {
+        D("failed to request. (%s:%s) \n", SDBD_CMD_PLUGIN_CAP, SDBD_CAP_TYPE_INTER_SHELL);
+        snprintf(g_capabilities.intershell_support, sizeof(g_capabilities.intershell_support),
+                    "%s", DISABLED);
+    }
+
+
+    // File push/pull support
+    if(!request_plugin_cmd(SDBD_CMD_PLUGIN_CAP, SDBD_CAP_TYPE_FILESYNC,
+                            g_capabilities.filesync_support,
+                            sizeof(g_capabilities.filesync_support))) {
+        D("failed to request. (%s:%s) \n", SDBD_CMD_PLUGIN_CAP, SDBD_CAP_TYPE_FILESYNC);
+        snprintf(g_capabilities.filesync_support, sizeof(g_capabilities.filesync_support),
+                    "%s", DISABLED);
+    }
+
+
+    // USB protocol support
+    if(!request_plugin_cmd(SDBD_CMD_PLUGIN_CAP, SDBD_CAP_TYPE_USBPROTO,
+                            g_capabilities.usbproto_support,
+                            sizeof(g_capabilities.usbproto_support))) {
+        D("failed to request. (%s:%s) \n", SDBD_CMD_PLUGIN_CAP, SDBD_CAP_TYPE_USBPROTO);
+        snprintf(g_capabilities.usbproto_support, sizeof(g_capabilities.usbproto_support),
+                    "%s", DISABLED);
+    }
+
+
+    // Socket protocol support
+    if(!request_plugin_cmd(SDBD_CMD_PLUGIN_CAP, SDBD_CAP_TYPE_SOCKPROTO,
+                            g_capabilities.sockproto_support,
+                            sizeof(g_capabilities.sockproto_support))) {
+        D("failed to request. (%s:%s) \n", SDBD_CMD_PLUGIN_CAP, SDBD_CAP_TYPE_SOCKPROTO);
+        snprintf(g_capabilities.sockproto_support, sizeof(g_capabilities.sockproto_support),
+                    "%s", DISABLED);
+    }
+
+
+    // Root command support
+    if(!request_plugin_cmd(SDBD_CMD_PLUGIN_CAP, SDBD_CAP_TYPE_ROOTONOFF,
+                            g_capabilities.rootonoff_support,
+                            sizeof(g_capabilities.rootonoff_support))) {
+        D("failed to request. (%s:%s) \n", SDBD_CMD_PLUGIN_CAP, SDBD_CAP_TYPE_ROOTONOFF);
+        snprintf(g_capabilities.rootonoff_support, sizeof(g_capabilities.rootonoff_support),
+                    "%s", DISABLED);
+    }
+
+
+    // Zone support
+    ret = is_container_enabled();
+    snprintf(g_capabilities.zone_support, sizeof(g_capabilities.zone_support),
+                "%s", ret == 1 ? ENABLED : DISABLED);
+
+
+    // Multi-User support
+    // TODO: get this information from platform.
+    snprintf(g_capabilities.multiuser_support, sizeof(g_capabilities.multiuser_support),
+                "%s", DISABLED);
+
+
+    // Window size synchronization support
+    snprintf(g_capabilities.syncwinsz_support, sizeof(g_capabilities.syncwinsz_support),
+                "%s", ENABLED);
+
+
+    // Profile name
+    ret = system_info_get_platform_string("http://tizen.org/feature/profile", &value);
+    if (ret != SYSTEM_INFO_ERROR_NONE) {
+        snprintf(g_capabilities.profile_name, sizeof(g_capabilities.profile_name),
+                    "%s", UNKNOWN);
+        D("fail to get profile name:%d\n", errno);
+    } else {
+        snprintf(g_capabilities.profile_name, sizeof(g_capabilities.profile_name),
+                    "%s", value);
+        if (value != NULL) {
+            free(value);
+        }
+    }
+
+
+    // Vendor name
+    ret = system_info_get_platform_string("http://tizen.org/system/manufacturer", &value);
+    if (ret != SYSTEM_INFO_ERROR_NONE) {
+        snprintf(g_capabilities.vendor_name, sizeof(g_capabilities.vendor_name),
+                    "%s", UNKNOWN);
+        D("fail to get the Vendor name:%d\n", errno);
+    } else {
+        snprintf(g_capabilities.vendor_name, sizeof(g_capabilities.vendor_name),
+                    "%s", value);
+        if (value != NULL) {
+            free(value);
+        }
+    }
+
+
+    // Platform version
+    ret = system_info_get_platform_string("http://tizen.org/feature/platform.version", &value);
+    if (ret != SYSTEM_INFO_ERROR_NONE) {
+        snprintf(g_capabilities.platform_version, sizeof(g_capabilities.platform_version),
+                    "%s", UNKNOWN);
+        D("fail to get platform version:%d\n", errno);
+    } else {
+        snprintf(g_capabilities.platform_version, sizeof(g_capabilities.platform_version),
+                    "%s", value);
+        if (value != NULL) {
+            free(value);
+        }
+    }
+
+
+    // Product version
+    if(!request_plugin_cmd(SDBD_CMD_PLUGIN_CAP, SDBD_CAP_TYPE_PRODUCT_VER,
+                            g_capabilities.product_version,
+                            sizeof(g_capabilities.product_version))) {
+        D("failed to request. (%s:%s) \n", SDBD_CMD_PLUGIN_CAP, SDBD_CAP_TYPE_PRODUCT_VER);
+        snprintf(g_capabilities.product_version, sizeof(g_capabilities.product_version),
+                    "%s", UNKNOWN);
+    }
+
+
+    // Sdbd version
+    snprintf(g_capabilities.sdbd_version, sizeof(g_capabilities.sdbd_version),
+                "%d.%d.%d", SDB_VERSION_MAJOR, SDB_VERSION_MINOR, SDB_VERSION_PATCH);
+
+
+    // Sdbd plugin version
+    if(!request_plugin_cmd(SDBD_CMD_PLUGIN_CAP, SDBD_CAP_TYPE_PLUGIN_VER,
+                            g_capabilities.sdbd_plugin_version,
+                            sizeof(g_capabilities.sdbd_plugin_version))) {
+        D("failed to request. (%s:%s) \n", SDBD_CMD_PLUGIN_CAP, SDBD_CAP_TYPE_PLUGIN_VER);
+        snprintf(g_capabilities.sdbd_plugin_version, sizeof(g_capabilities.sdbd_plugin_version),
+                    "%s", UNKNOWN);
+    }
 }
 #endif /* !SDB_HOST */
 
+static int is_support_usbproto()
+{
+    return (!strncmp(g_capabilities.usbproto_support, SDBD_CAP_RET_ENABLED, strlen(SDBD_CAP_RET_ENABLED)));
+}
+
+static int is_support_sockproto()
+{
+    return (!strncmp(g_capabilities.sockproto_support, SDBD_CAP_RET_ENABLED, strlen(SDBD_CAP_RET_ENABLED)));
+}
+
 int sdb_main(int is_daemon, int server_port)
 {
 #if !SDB_HOST
+    load_sdbd_plugin();
+    init_capabilities();
+
     init_drop_privileges();
     init_sdk_requirements();
+    if (!request_plugin_verification(SDBD_CMD_VERIFY_LAUNCH, NULL)) {
+        D("sdbd should be launched in develop mode.\n");
+        return -1;
+    }
+
     umask(000);
 #endif
 
@@ -1325,18 +2120,64 @@ int sdb_main(int is_daemon, int server_port)
         char local_name[30];
         build_local_name(local_name, sizeof(local_name), server_port);
         if(install_listener(local_name, "*smartsocket*", NULL)) {
-            D("Cannot install listener (smartsocket)\n");
-            return 1;
-            //exit(1);
+            exit(1);
         }
     }
 
-    if (!is_emulator()) {
+    hostshell_mode = 1;
+
+ /* Not support zone feature yet */
+ /*
+       if (is_container_enabled()) {
+               D("container feature permitted\n");
+
+               // register call-back to check state of zone
+               create_zone_check_thread();
+
+               // check if zone is started before sdbd, in the case sdbd does not get notified.
+               char** zone_list;
+               zone_list = get_zone_list();
+               if (zone_list != NULL) {
+                       D("set zone mode on\n");
+                       sdb_mutex_lock(&zone_check_lock);
+                       if(!initial_zone_mode_check) {
+                               initial_zone_mode_check = 1;
+                               hostshell_mode = 0;
+                               // execute processes needed by each zone
+                               if (zone_list) {
+                                       int i;
+                                       for (i = 0; *(zone_list + i); i++) {
+                                               D("Name of zone which executes required processes (in sdb_main) : %s \n", *(zone_list + i));
+                                               // if zone name has prefix as '/', remove it
+                                               if (!strncmp(*(zone_list + i), "\/", 1)) {
+                                                       execute_required_process_in_each_zone(
+                                                                       (*(zone_list + i) + 1));
+                                               } else {
+                                                       execute_required_process_in_each_zone(*(zone_list + i));
+                                               }
+                                               free(*(zone_list + i));
+                                       }
+                                       free(zone_list);
+                               }
+                       }
+                       sdb_mutex_unlock(&zone_check_lock);
+               } else {
+                       D("not found any zone yet, denied mode on\n");
+                       sdb_sleep_ms(500);
+               }
+       } else {
+               D("container feature not permitted, set host mode on\n");
+               initial_zone_mode_check = 1;
+               hostshell_mode = 1;
+       }
+*/
+    if (is_support_usbproto()) {
         // listen on USB
         usb_init();
         // listen on tcp
         //local_init(DEFAULT_SDB_LOCAL_TRANSPORT_PORT);
-    } else {
+    }
+    if (is_support_sockproto()){
         // listen on default port
         local_init(DEFAULT_SDB_LOCAL_TRANSPORT_PORT);
     }
@@ -1484,16 +2325,12 @@ int copy_packet(apacket* dest, apacket* src) {
     dest->ptr = src->ptr;
     dest->len = src->len;
 
-    memcpy(&(dest->msg), &(src->msg), sizeof(amessage));
-    // TODO: should verify what if data length is over MAX_PAYLOAD
     int data_length = src->msg.data_length;
     if(data_length > MAX_PAYLOAD) {
         data_length = MAX_PAYLOAD;
-        dest->msg.data_length = data_length;
-        D("copy packet error: %d > MAX_PAYLOAD\n", src->msg.data_length);
     }
+    memcpy(&(dest->msg), &(src->msg), sizeof(amessage) + data_length);
 
-    memcpy(&(dest->data), &(src->data), data_length);
     return 0;
 }
 
@@ -1714,7 +2551,7 @@ int main(int argc, char **argv)
 #endif
 #if !SDB_HOST
     if (daemonize() < 0)
-        fatal("daemonize() failed: (errno:%d)", errno);
+        fatal("daemonize() failed: errno:%d", errno);
 #endif
 
     start_device_log();
index 6e228fe..c030dba 100644 (file)
--- a/src/sdb.h
+++ b/src/sdb.h
 #define __SDB_H
 
 #include <limits.h>
+#include <stddef.h>
 
 #include "transport.h"  /* readx(), writex() */
+#include "fdevent.h"
+#include "sdbd_plugin.h"
 
 #define MAX_PAYLOAD 4096
 
@@ -34,7 +37,8 @@
 #define A_VERSION 0x02000000        // SDB protocol version
 
 #define SDB_VERSION_MAJOR 2         // Used for help/version information
-#define SDB_VERSION_MINOR 1         // Used for help/version information
+#define SDB_VERSION_MINOR 2         // Used for help/version information
+#define SDB_VERSION_PATCH 31        // Used for help/version information
 
 #define SDB_SERVER_VERSION 0        // Increment this when we want to force users to start a new sdb server
 
@@ -87,11 +91,6 @@ struct asocket {
         */
     int    closing;
 
-        /* flag: quit adbd when both ends close the
-        ** local service socket
-        */
-    int    exit_on_close;
-
         /* the asocket we are connected to
         */
 
@@ -223,6 +222,53 @@ struct alistener
     adisconnect  disconnect;
 };
 
+#define UNKNOWN "unknown"
+#define INFOBUF_MAXLEN 64
+#define INFO_VERSION "2.2.0"
+typedef struct platform_info {
+    char platform_info_version[INFOBUF_MAXLEN];
+    char model_name[INFOBUF_MAXLEN]; // Emulator
+    char platform_name[INFOBUF_MAXLEN]; // Tizen
+    char platform_version[INFOBUF_MAXLEN]; // 2.2.1
+    char profile_name[INFOBUF_MAXLEN]; // 2.2.1
+} pinfo;
+
+#define ENABLED "enabled"
+#define DISABLED "disabled"
+#define CPUARCH_ARMV6 "armv6"
+#define CPUARCH_ARMV7 "armv7"
+#define CPUARCH_X86 "x86"
+#define CAPBUF_SIZE 4096
+#define CAPBUF_ITEMSIZE 32
+typedef struct platform_capabilities
+{
+    char secure_protocol[CAPBUF_ITEMSIZE];      // enabled or disabled
+    char intershell_support[CAPBUF_ITEMSIZE];   // enabled or disabled
+    char filesync_support[CAPBUF_ITEMSIZE];     // push or pull or pushpull or disabled
+    char rootonoff_support[CAPBUF_ITEMSIZE];    // enabled or disabled
+    char zone_support[CAPBUF_ITEMSIZE];         // enabled or disabled
+    char multiuser_support[CAPBUF_ITEMSIZE];    // enabled or disabled
+    char syncwinsz_support[CAPBUF_ITEMSIZE];    // enabled or disabled
+    char usbproto_support[CAPBUF_ITEMSIZE];     // enabled or disabled
+    char sockproto_support[CAPBUF_ITEMSIZE];    // enabled or disabled
+
+    char cpu_arch[CAPBUF_ITEMSIZE];             // cpu architecture (ex. x86)
+    char profile_name[CAPBUF_ITEMSIZE];         // profile name (ex. mobile)
+    char vendor_name[CAPBUF_ITEMSIZE];          // vendor name (ex. Tizen)
+
+    char platform_version[CAPBUF_ITEMSIZE];     // platform version (ex. 2.3.0)
+    char product_version[CAPBUF_ITEMSIZE];      // product version (ex. 1.0)
+    char sdbd_version[CAPBUF_ITEMSIZE];         // sdbd version
+    char sdbd_plugin_version[CAPBUF_ITEMSIZE];  // sdbd plugin version
+} pcap;
+pcap g_capabilities;
+
+#define SDBD_PLUGIN_PATH    "/usr/lib/libsdbd_plugin.so"
+#define SDBD_PLUGIN_INTF    "sdbd_plugin_cmd_proc"
+typedef int (*SDBD_PLUGIN_CMD_PROC_PTR)(const char*, const char*, sdbd_plugin_param);
+extern SDBD_PLUGIN_CMD_PROC_PTR sdbd_plugin_cmd_proc;
+int request_plugin_cmd(const char* cmd, const char* in_buf, char *out_buf, unsigned int out_len);
+int request_plugin_verification(const char* cmd, const char* in_buf);
 
 void print_packet(const char *label, apacket *p);
 
@@ -322,14 +368,14 @@ void log_service(int fd, void *cookie);
 void remount_service(int fd, void *cookie);
 char * get_log_file_path(const char * log_name);
 
-int rootshell_mode;// 0: developer, 1: root
-int usb_mode; // 2:mtp 6:rndis
+int rootshell_mode; // 0: developer, 1: root
+int hostshell_mode; // 0: foreground zone, 1: host  2: denied
+int booting_done; // 0: platform booting is in progess 1: platform booting is done
 
 // This is the users and groups config for the platform
 
 #define SID_ROOT        0    /* traditional unix root user */
 #define SID_TTY         5    /* group for /dev/ptmx */
-#define SID_APP         5000 /* application */
 #define SID_DEVELOPER   5100 /* developer with SDK */
 #define SID_APP_LOGGING 6509
 #define SID_SYS_LOGGING 6527
@@ -345,6 +391,9 @@ void set_root_privileges();
 int get_emulator_forward_port(void);
 int get_emulator_name(char str[], int str_size);
 int get_device_name(char str[], int str_size);
+int get_emulator_hostip(char str[], int str_size);
+int get_emulator_guestip(char str[], int str_size);
+
 /* packet allocator */
 apacket *get_apacket(void);
 void put_apacket(apacket *p);
@@ -462,7 +511,7 @@ int  local_connect_arbitrary_ports(int console_port, int sdb_port, const char *d
 void usb_init();
 void usb_cleanup();
 int usb_write(usb_handle *h, const void *data, int len);
-int usb_read(usb_handle *h, void *data, int len);
+int usb_read(usb_handle *h, void *data, unsigned len);
 int usb_close(usb_handle *h);
 void usb_kick(usb_handle *h);
 
@@ -496,6 +545,8 @@ int handle_host_request(char *service, transport_type ttype, char* serial, int r
 int copy_packet(apacket* dest, apacket* src);
 
 int is_emulator(void);
+int is_container_enabled(void);
+int has_container(void);
 #define DEFAULT_DEVICENAME "unknown"
 
 #if SDB_HOST /* tizen-specific */
@@ -510,4 +561,6 @@ int read_line(const int fd, char* ptr, const size_t maxlen);
 #endif
 
 #define USB_NODE_FILE "/dev/samsung_sdb"
-#define DEBUG_MODE_KEY "db/usb/sel_mode"
+#define CMD_ATTACH  "/usr/bin/vsm-attach"
+#define CMD_FOREGROUND "/usr/bin/vsm-foreground"
+#define CMD_LIST "/usr/bin/vsm-list"
diff --git a/src/sdbd_plugin.h b/src/sdbd_plugin.h
new file mode 100644 (file)
index 0000000..81c590a
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __SDBD_PLUGIN_H
+#define __SDBD_PLUGIN_H
+
+#include <string.h>
+
+/* plugin commands */
+#define SDBD_CMD_PLUGIN_CAP             "plugin_capability"
+#define SDBD_CMD_VERIFY_SHELLCMD        "verify_shell_cmd"
+#define SDBD_CMD_CONV_SHELLCMD          "convert_shell_cmd"
+#define SDBD_CMD_VERIFY_PEERIP          "verify_peer_ip"
+#define SDBD_CMD_VERIFY_LAUNCH          "verify_sdbd_launch"
+#define SDBD_CMD_VERIFY_ROOTCMD         "verify_root_cmd"
+
+/* plugin capabilities */
+#define SDBD_CAP_TYPE_SECURE            "secure_protocol_support"
+#define SDBD_CAP_TYPE_INTER_SHELL       "interactive_shell_support"
+#define SDBD_CAP_TYPE_FILESYNC          "file_sync_support"
+#define SDBD_CAP_TYPE_USBPROTO          "usb_protocol_support"
+#define SDBD_CAP_TYPE_SOCKPROTO         "socket_protocol_support"
+#define SDBD_CAP_TYPE_ROOTONOFF         "root_onoff_support"
+#define SDBD_CAP_TYPE_PLUGIN_VER        "sdbd_plugin_version"
+#define SDBD_CAP_TYPE_PRODUCT_VER       "product_version"
+/* capability return string */
+#define SDBD_CAP_RET_ENABLED            "enabled"
+#define SDBD_CAP_RET_DISABLED           "disabled"
+#define SDBD_CAP_RET_PUSH               "push"
+#define SDBD_CAP_RET_PULL               "pull"
+#define SDBD_CAP_RET_PUSHPULL           "pushpull"
+
+/* verification return string */
+#define SDBD_RET_VALID                  "valid"
+#define SDBD_RET_INVALID                "invalid"
+
+/* proc interface return value */
+#define SDBD_PLUGIN_RET_SUCCESS         (0)
+#define SDBD_PLUGIN_RET_FAIL            (-1)
+#define SDBD_PLUGIN_RET_NOT_SUPPORT     (-2)
+
+/* utility macro */
+#define SDBD_CMP_CMD(cmd, type)                             \
+    ((strlen(cmd) == strlen(SDBD_CMD_##type)                \
+    && !strncmp(cmd, SDBD_CMD_##type, strlen(cmd)))?1:0)
+
+#define SDBD_CMP_CAP(cap, type)                             \
+    ((strlen(cap) == (strlen(SDBD_CAP_TYPE_##type))         \
+    && !strncmp(cap, SDBD_CAP_TYPE_##type, strlen(cap)))?1:0)
+
+/* out parameter structure */
+#define SDBD_SHELL_CMD_MAX      4096
+#define SDBD_PLUGIN_OUTBUF_MAX  4096
+typedef struct sdbd_plugin_param {
+    unsigned int len;
+    char *data;
+} sdbd_plugin_param;
+
+/* log system */
+// 1. set the environment value. : SDB_TRACE=all
+// 2. restart the sdbd deamon.
+// 3. log is output to the /tmp/sdbd-[date].txt
+#define SDBD_PLUGIN_LOG(...)                \
+        fprintf(stderr, "%s::%s():",        \
+                __FILE__, __FUNCTION__);    \
+        fprintf(stderr, __VA_ARGS__);
+
+#endif
index 971e8d8..b4aca01 100644 (file)
 #include "utils.h"
 
 struct sudo_command root_commands[] = {
-    /* 0 */ {"da_command", "/usr/bin/da_command"},
-    /* 1 */ {"profile", "/usr/bin/profile_command"},
-    /* 2 */ {"rm1", "rm"},
-    /* 3 */ {"rm2", "/bin/rm"},
-    /* end */ {NULL, NULL}
+    /* 0 */
+    { "profile", "/usr/bin/profile_command",
+        { "killmanager",
+        "runmanager",
+        "findunittest",
+        "process",
+        "getversion",
+        "killvalgrind",
+        "getprobemap",
+        NULL
+        }
+    },
+    /* end */
+    { NULL, NULL, NULL }
 };
 
 static struct command_suffix
@@ -38,19 +47,11 @@ static struct command_suffix CMD_SUFFIX_DENY_KEYWORD[] = {
         /* 1 */   {"redirect", ">"},
         /* 2 */   {"semicolon", ";"}, // separated list is executed
         /* 3 */   {"and", "&"},
+        /* 4 */   {"command_substitution1", "$"},
+        /* 5 */   {"command_substitution2", "`"},
         /* end */ {NULL, NULL}
 };
 
-struct arg_permit_rule sdk_arg_permit_rule[] = {
-    /* 0 */ {"gcove_env1", "^GCOV_PREFIX=((/opt/apps)|(/opt/usr/apps))/[a-zA-Z0-9]{10}/data$", 1},
-    /* 1 */ {"gcove_env2", "GCOV_PREFIX_STRIP=0", 0},
-    /* 2 */ {"gcove_env3", "LD_LIBRARY_PATH=/home/developer/sdk_tools/gtest/usr/lib:$LD_LIBRARY_PATH", 0},
-    /* 3 */ {"gcove_env4", "TIZEN_LAUNCH_MODE=debug", 0},
-    /* 4 */ {"da_env1", "LD_PRELOAD=/usr/lib/da_probe_osp.so", 0},
-    /* 5 */ {"gcove_arg1", "^\\-\\-gtest_output=xml:((/opt/apps)|(/opt/usr/apps))/[a-zA-Z0-9]{10}/data/[a-zA-Z0-9_\\-]{1,30}\\.xml$", 1},
-    /* end */ {NULL, NULL, 0}
-};
-
 /**
  * return 1 if the arg is arrowed, otherwise 0 is denied
  */
@@ -150,66 +151,26 @@ int verify_root_commands(const char *arg1) {
     }
     index = is_root_commands(tokens[0]);
     if (index == -1) {
-        if (exec_app_standalone(arg1)) {
-            ret = 1;
-        } else {
-            return 0; // just keep going to execute normal commands
-        }
+        return 0; // just keep going to execute normal commands
     }
 
     switch (index) {
-    case 0: { // in case of da_command
+    // in case of profile_command
+    case 0: {
         ret = 0;
-        if (!is_cmd_suffix_denied(arg1)) {
-            ret = 1;
-        }
-        // this is exception to allow suffix
-        if (cnt == 5 && !strcmp(tokens[1], "process")
-                && !strcmp(tokens[2], "|")
-                && !strcmp(tokens[3], "grep")
-                && !is_cmd_suffix_denied(tokens[4])) {
-                ret = 1;
-        }
-        break;
-    }
-    case 1: { // in case of oprofile_command
-        ret = 0;
-        if (!is_cmd_suffix_denied(arg1)) {
-            ret = 1;
-        }
-        if (!strcmp(tokens[1], "valgrind") && cnt >= 3) {
-            char *appid = NULL;
-            // the tokens[2] should be apppath
-            int rc = smack_lgetlabel(tokens[2], &appid, SMACK_LABEL_ACCESS);
-            if (rc == 0 && appid != NULL) {
-                if (apply_sdb_rules(SDBD_LABEL_NAME, appid, "rwax") < 0) {
-                    D("unable to set %s %s rules\n", SDBD_LABEL_NAME, appid);
-                } else {
-                    D("apply rule to '%s %s rwax' rules\n", SDBD_LABEL_NAME, appid);
+        if (!is_cmd_suffix_denied(arg1) && (cnt == 2)) {
+            // check if command is used with permitted arguments
+            for (i = 0; root_commands[0].arguments[i] != NULL; i++) {
+                if (!strncmp(tokens[1], root_commands[0].arguments[i], strlen(tokens[1]))){
+                    D("found permitted arguments :%s\n", tokens[1]);
+                    ret = 1;
+                    break;
                 }
-                if (apply_sdb_rules(appid, SDBD_LABEL_NAME, "rwax") < 0) {
-                    D("unable to set %s %s rules\n", appid, SDBD_LABEL_NAME);
-                } else {
-                    D("apply rule to '%s %s rwax' rules\n", appid, SDBD_LABEL_NAME);
-                }
-                //apply_app_process();
 
-                free(appid);
             }
-            D("standalone launch for valgrind\n");
-        }
-
-        break;
-    }
-    case 2:
-    case 3:
-    { // in case of rm to remove the temporary package file
-        if (is_cmd_suffix_denied(arg1)) {
-            ret = 0;
-            break;
-        }
-        if (is_pkg_file_path(tokens[1])) {
-            ret = 1;
+            if (ret == 0) {
+                D("not found permitted arguments :%s\n", tokens[1]);
+            }
         }
         break;
     }
@@ -227,15 +188,6 @@ int verify_root_commands(const char *arg1) {
     return ret;
 }
 
-int verify_app_path(const char* path) {
-    char buf[PATH_MAX];
-
-    snprintf(buf, sizeof buf, "^((%s)|(%s))/[a-zA-Z0-9]{%d}/bin/[a-zA-Z0-9_\\-]{1,}(\\.exe)?$", APP_INSTALL_PATH_PREFIX1, APP_INSTALL_PATH_PREFIX2, 10);
-    int reg_cmp = regcmp(buf, path);
-
-    return reg_cmp;
-}
-
 int regcmp(const char* pattern, const char* str) {
     regex_t regex;
     int ret;
@@ -260,326 +212,6 @@ int regcmp(const char* pattern, const char* str) {
     return 0;
 }
 
-int env_verify(const char* arg) {
-    int i;
-    for (i=0; sdk_arg_permit_rule[i].name != NULL; i++) {
-        if (sdk_arg_permit_rule[i].expression == 0) {
-            if (!strcmp(sdk_arg_permit_rule[i].pattern, arg)) {
-                D("success to set %s\n", arg);
-                return 1;
-            }
-        } else if (sdk_arg_permit_rule[i].expression == 1) {
-            if (regcmp(sdk_arg_permit_rule[i].pattern, arg)) {
-                D("success to set %s\n", arg);
-                return 1;
-            }
-        }
-    }
-    D("failed to set %s\n", arg);
-    return 0;
-}
-
-int exec_app_standalone(const char* path) {
-    char *tokens[MAX_TOKENS];
-    int ret = 0;
-    int cnt = 0;
-    int flag = 1;
-    int i=0;
-
-    cnt = tokenize(path, " ", tokens, MAX_TOKENS);
-    for (i=0; i<cnt; i++) {
-        D("tokenize: %dth: %s\n", i, tokens[i]);
-
-        if (!strcmp("export", tokens[i])) {
-            flag = 0;
-            i++;
-            if (i>=cnt) break;
-            if (env_verify(tokens[i])) {
-                flag = 1;
-            }
-            i++;
-            if (i>=cnt) break;
-            if (!strcmp("&&", tokens[i])) {
-                continue;
-            }
-        }
-        if (flag == 0) {
-            // TODO: check evn setting
-        }
-
-        if(!strcmp(tokens[i], SDK_LAUNCH_PATH)) {
-            int pid = 0;
-            char* pkg_id = NULL;
-            char* executable = NULL;
-            ++i;
-            while( i < cnt ) {
-                if(!strcmp(tokens[i], "-attach")) {
-                    if(++i < cnt) {
-                        char* pid_pattern = "[1-9][0-9]{2,5}";
-                        if (regcmp(pid_pattern, tokens[i])) {
-                            pid = atoi(tokens[i]);
-                        }
-                    }
-                }
-                else if(!strcmp(tokens[i], "-p")) {
-                    if(++i < cnt) {
-                        pkg_id = tokens[i];
-                    }
-                }
-                else if(!strcmp(tokens[i], "-e")) {
-                    if(++i < cnt) {
-                        executable = tokens[i];
-                    }
-                }
-                i++;
-            }
-            if(pid > 0) {
-                char cmdline[128];
-                if (pid) {
-                    snprintf(cmdline, sizeof(cmdline), "/proc/%d/cmdline", pid);
-                    int fd = unix_open(cmdline, O_RDONLY);
-                    if (fd >= 0) {
-                        if(read_line(fd, cmdline, sizeof(cmdline))) {
-                            if (set_smack_rules_for_gdbserver(cmdline, 1)) {
-                                ret = 1;
-                            }
-                        }
-                        sdb_close(fd);
-                    }
-                }
-            }
-            break;
-        }
-        // TODO: i length check
-        else if (!strcmp(tokens[i], GDBSERVER_PATH) || !strcmp(tokens[i], GDBSERVER_PLATFORM_PATH)) { //gdbserver :11 --attach 2332 (cnt=4,)
-            char *gdb_attach_arg_pattern = "^:[1-9][0-9]{2,5} \\-\\-attach [1-9][0-9]{2,5}$";
-            int argcnt = cnt-i-1;
-            if (argcnt == 3 && !strcmp("--attach", tokens[i+2])) {
-                char cmdline[128];
-                int pid = 0;
-                D("parsing.... debug attach mode\n");
-                snprintf(cmdline, sizeof(cmdline), "%s %s %s",tokens[i+1], tokens[i+2], tokens[i+3]);
-                if (regcmp(gdb_attach_arg_pattern, cmdline)) {
-                    char cmdline[128];
-                    pid = atoi(tokens[i+3]);
-                    if (pid) {
-                        snprintf(cmdline, sizeof(cmdline), "/proc/%d/cmdline", pid);
-                        int fd = unix_open(cmdline, O_RDONLY);
-                        if (fd >= 0) {
-                            if(read_line(fd, cmdline, sizeof(cmdline))) {
-                                if (set_smack_rules_for_gdbserver(cmdline, 1)) {
-                                    ret = 1;
-                                }
-                            }
-                            sdb_close(fd);
-                        }
-                    }
-                }
-            }
-            else if (argcnt >= 2) {
-                if(should_drop_privileges() == 0 || verify_app_path(tokens[i+2])) {
-                    D("parsing.... debug run as mode\n");
-                    if (set_smack_rules_for_gdbserver(tokens[i+2], 0)) {
-                        ret = 1;
-                    }
-                }
-            }
-            D("finished debug launch mode\n");
-        } else {
-            if (verify_app_path(tokens[i])) {
-                char *path = tokens[i];
-                char *appid = NULL;
-                int rc = smack_lgetlabel(path, &appid, SMACK_LABEL_ACCESS);
-                if (rc == 0 && appid != NULL) {
-                    if (apply_sdb_rules(SDBD_LABEL_NAME, appid, "rwax") < 0) {
-                        D("unable to set sdbd rules to %s %s rwax\n", SDBD_LABEL_NAME, appid);
-                    } else {
-                        D("set sdbd rules to %s %s rwax\n", SDBD_LABEL_NAME, appid);
-                    }
-                    if (apply_sdb_rules(appid, SDBD_LABEL_NAME, "rwax") < 0) {
-                        D("unable to set sdbd rules to %s %s rwax\n", appid, SDBD_LABEL_NAME);
-                    } else {
-                        D("set sdbd rules to %s %s rwax\n", appid, SDBD_LABEL_NAME);
-                    }
-                    if (smack_set_label_for_self(appid) != -1) {
-                        D("set smack lebel [%s] appid to %s\n", appid, SMACK_LEBEL_SUBJECT_PATH);
-                        apply_app_process();
-                        ret = 1;
-                    } else {
-                        D("unable to open %s due to (errno:%d)\n", SMACK_LEBEL_SUBJECT_PATH, errno);
-                    }
-                    free(appid);
-                }
-                D("standalone launch\n");
-            }
-        }
-        // TODO: verify arguments
-        break;
-    }
-
-    if (cnt) {
-        free_strings(tokens, cnt);
-    }
-    return ret;
-}
-
-/**
- * free after use it
- */
-char* clone_gdbserver_label_from_app(const char* app_path) {
-    char *new_appid = NULL;
-    char appid[APPID_MAX_LENGTH+1];
-    char *buffer = NULL;
-
-#if 0
-    if (!verify_app_path(app_path)) {
-        D("not be able to access %s\n", app_path);
-        return NULL;
-    }
-#endif
-
-    int rc = smack_lgetlabel(app_path, &buffer, SMACK_LABEL_ACCESS);
-
-    if (rc == 0 && buffer != NULL) {
-        s_strncpy(appid, buffer, sizeof appid);
-        free(buffer);
-    } else {
-        appid[0] = '_';
-        appid[1] = '\0';
-    }
-    new_appid = (char *)malloc(sizeof(appid)+1);
-    if (new_appid == NULL) {
-        D("could not allocate buffer for new appid'\n");
-        return NULL;
-    }
-    strncpy(new_appid, appid, APPID_MAX_LENGTH);
-    // Do not label to gdbserver executable
-/*
-    if (new_appid != NULL) {
-        rc = smack_lsetlabel(GDBSERVER_PATH, new_appid, SMACK_LABEL_ACCESS);
-        if (rc < 0) {
-            D("unable to set access smack label: %s to %s\n", GDBSERVER_PATH, new_appid);
-        }
-        D("set access smack label: %s to %s\n", GDBSERVER_PATH, new_appid);
-
-        rc = smack_lsetlabel(GDBSERVER_PATH, new_appid, SMACK_LABEL_EXEC);
-        if (rc < 0) {
-            D("unable to set execute smack label: %s to %s\n", GDBSERVER_PATH, new_appid);
-        }
-        D("set execute smack label: %s to %s\n", GDBSERVER_PATH, new_appid);
-    }
-*/
-    return new_appid;
-}
-
-int set_smack_rules_for_gdbserver(const char* apppath, int mode) {
-    // FIXME: set gdbfolder to 755 also
-    if(sdb_chmod(GDBSERVER_PATH, S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH, 1) < 0)
-    {
-        D("unable to set 755 to %s", GDBSERVER_PATH);
-    }
-
-    // in case of debug as mode
-    char *new_appid = clone_gdbserver_label_from_app(apppath);
-    if (new_appid != NULL) {
-        if (apply_sdb_rules(SDBD_LABEL_NAME, new_appid, "w") < 0) {
-            D("unable to set sdbd rules\n");
-        }
-        if (apply_sdb_rules(new_appid, SDK_HOME_LABEL_NAME, "rx") < 0) {
-            D("unable to set sdbd home rules\n");
-        }
-        if (smack_set_label_for_self(new_appid) != -1) {
-            D("set smack lebel [%s] appid to %s\n", new_appid, SMACK_LEBEL_SUBJECT_PATH);
-            // apply app precess only if not attach mode
-            if (mode == 0) {
-                apply_app_process();
-            }
-        } else {
-            D("unable to open %s due to (errno:%d)\n", SMACK_LEBEL_SUBJECT_PATH, errno);
-        }
-        free(new_appid);
-        return 1;
-    }
-    // TODO: in case of attach mode
-    return 0;
-}
-
-int apply_sdb_rules(const char* subject, const char* object, const char* access_type) {
-    struct smack_accesses *rules = NULL;
-    int ret = 0;
-
-    if (smack_accesses_new(&rules))
-        return -1;
-
-    if (smack_accesses_add(rules, subject, object, access_type)) {
-        smack_accesses_free(rules);
-        return -1;
-    }
-
-    ret = smack_accesses_apply(rules);
-    smack_accesses_free(rules);
-
-    return ret;
-}
-
-void apply_app_process() {
-    set_appuser_groups();
-
-    if (setgid(SID_APP) != 0) {
-        //fprintf(stderr, "set group id failed errno: %d\n", errno);
-        exit(1);
-    }
-
-    if (setuid(SID_APP) != 0) {
-        //fprintf(stderr, "set user id failed errno: %d\n", errno);
-        exit(1);
-    }
-}
-
-void set_appuser_groups(void) {
-
-    int fd = 0;
-    char buffer[5];
-    gid_t t_gid = -1;
-    gid_t groups[APP_GROUPS_MAX]={0,};
-    int cnt = 0;
-
-    //groups[cnt++] = SID_DEVELOPER;
-    fd = sdb_open(APP_GROUP_LIST, O_RDONLY);
-    if (fd < 0) {
-        D("cannot get app's group lists from %s", APP_GROUP_LIST);
-        return;
-    }
-    for (;;) {
-        if (read_line(fd, buffer, sizeof buffer) < 0) {
-            break;
-        }
-        t_gid = strtoul(buffer, 0, 10);
-        errno = 0;
-        if(errno != 0)
-        {
-            D("cannot change string to integer: [%s]\n", buffer);
-            continue;
-        }
-        if (t_gid) {
-            if (cnt < APP_GROUPS_MAX) {
-                groups[cnt++] = t_gid;
-            } else {
-                D("cannot add groups more than %d", APP_GROUPS_MAX);
-                break;
-            }
-        }
-    }
-    if (cnt > 0) {
-        if (setgroups(sizeof(groups) / sizeof(groups[0]), groups) != 0) {
-            sdb_close(fd);
-           fprintf(stderr, "set groups failed errno: %d\n", errno);
-           exit(1);
-        }
-    }
-    sdb_close(fd);
-}
-
 int is_root_commands(const char *command) {
     int i = -1;
     for(i = 0; root_commands[i].path != NULL; i++) {
index eed1709..a496c26 100644 (file)
@@ -5,11 +5,12 @@
 extern "C" {
 #endif
 
+#define PERMITTED_ARGUMENT_SIZE 20
 struct sudo_command
 {
   const char *command;
   const char *path;
-  //const char *arguments;
+  const char *arguments[PERMITTED_ARGUMENT_SIZE];
   //const char *regx;
   //int   permission; /* 0: root, 1: developer, 2: app*/
 };
@@ -38,13 +39,7 @@ struct arg_permit_rule
 int verify_root_commands(const char *arg1);
 int verify_app_path(const char* path);
 int regcmp(const char* pattern, const char* str);
-int exec_app_standalone(const char* path);
-char* clone_gdbserver_label_from_app(const char* app_path);
-int set_smack_rules_for_gdbserver(const char* apppath, int mode);
-void apply_app_process();
-void set_appuser_groups(void);
 int is_root_commands(const char *command);
-int apply_sdb_rules(const char* subject, const char* object, const char* access_type);
 int is_pkg_file_path(const char* path);
 
 #ifdef __cplusplus
index 93973f2..ae3fbbb 100644 (file)
 #endif
 
 #include "strutils.h"
-#include <system_info_internal.h>
+#include <system_info.h>
 #include <vconf.h>
 #include <limits.h>
 
+#include <termios.h>
+#include <sys/ioctl.h>
+
 typedef struct stinfo stinfo;
 
 struct stinfo {
@@ -82,6 +85,11 @@ static void dns_service(int fd, void *cookie)
 }
 #else
 
+static int is_support_interactive_shell()
+{
+    return (!strncmp(g_capabilities.intershell_support, SDBD_CAP_RET_ENABLED, strlen(SDBD_CAP_RET_ENABLED)));
+}
+
 #if 0
 extern int recovery_mode;
 
@@ -142,23 +150,35 @@ void restart_root_service(int fd, void *cookie)
 }
 #endif
 
+static int is_support_rootonoff()
+{
+    return (!strncmp(g_capabilities.rootonoff_support, SDBD_CAP_RET_ENABLED, strlen(SDBD_CAP_RET_ENABLED)));
+}
+
 void rootshell_service(int fd, void *cookie)
 {
     char buf[100];
     char *mode = (char*) cookie;
 
     if (!strcmp(mode, "on")) {
-        if (rootshell_mode == 1) {
-            //snprintf(buf, sizeof(buf), "Already changed to developer mode\n");
-            // do not show message
-        } else {
-            if (access("/bin/su", F_OK) == 0) {
-                rootshell_mode = 1;
-                //allows a permitted user to execute a command as the superuser
-                snprintf(buf, sizeof(buf), "Switched to 'root' account mode\n");
+        if (getuid() == 0) {
+            if (rootshell_mode == 1) {
+                //snprintf(buf, sizeof(buf), "Already changed to developer mode\n");
+                // do not show message
             } else {
-                snprintf(buf, sizeof(buf), "Permission denied\n");
+                if (is_support_rootonoff()) {
+                    rootshell_mode = 1;
+                    //allows a permitted user to execute a command as the superuser
+                    snprintf(buf, sizeof(buf), "Switched to 'root' account mode\n");
+                } else {
+                    snprintf(buf, sizeof(buf), "Permission denied\n");
+                }
+                writex(fd, buf, strlen(buf));
             }
+        } else {
+            D("need root permission for root shell: %d\n", getuid());
+            rootshell_mode = 0;
+            snprintf(buf, sizeof(buf), "Permission denied\n");
             writex(fd, buf, strlen(buf));
         }
     } else if (!strcmp(mode, "off")) {
@@ -167,8 +187,32 @@ void rootshell_service(int fd, void *cookie)
             snprintf(buf, sizeof(buf), "Switched to 'developer' account mode\n");
             writex(fd, buf, strlen(buf));
         }
+    } else if ((!strcmp(mode, "hoston")) && (is_container_enabled())) {
+        if (hostshell_mode == 1) {
+       //snprintf(buf, sizeof(buf), "Already changed to hostshell mode\n");
+       // do not show message
+       } else {
+            if (is_support_rootonoff()) {
+               hostshell_mode = 1;
+               snprintf(buf, sizeof(buf), "Switched to host shell mode\n");
+           } else {
+               snprintf(buf, sizeof(buf), "Permission denied\n");
+           }
+           writex(fd, buf, strlen(buf));
+       }
+    } else if ((!strcmp(mode, "hostoff")) && (is_container_enabled())) {
+        if (hostshell_mode == 1) {
+            if(has_container()) {
+                hostshell_mode = 0;
+                snprintf(buf, sizeof(buf), "Switched to foreground zone shell mode\n");
+                writex(fd, buf, strlen(buf));
+            } else {
+                snprintf(buf, sizeof(buf), "No foreground zone exists\n");
+                writex(fd, buf, strlen(buf));
+            }
+        }
     } else {
-        snprintf(buf, sizeof(buf), "Unknown command option\n");
+       snprintf(buf, sizeof(buf), "Unknown command option : %s\n", mode);
         writex(fd, buf, strlen(buf));
     }
     D("set rootshell to %s\n", rootshell_mode == 1 ? "root" : "developer");
@@ -200,7 +244,7 @@ void reboot_service(int fd, void *arg)
 
     ret = android_reboot(ANDROID_RB_RESTART2, 0, (char *) arg);
     if (ret < 0) {
-        snprintf(buf, sizeof(buf), "reboot failed: %s\n", strerror(errno));
+        snprintf(buf, sizeof(buf), "reboot failed: %s errno:%d\n", errno);
         writex(fd, buf, strlen(buf));
     }
     free(arg);
@@ -269,48 +313,6 @@ done:
 #endif
 #endif
 
-void rndis_config_service(int fd, void *cookie)
-{
-    char buf[100];
-    int val = 0;
-    char* mode = (char*) cookie;
-
-    usb_mode = 0;
-    if (vconf_get_int(DEBUG_MODE_KEY, &val)) {
-        D("Failed to get debug mode\n");
-        sdb_close(fd);
-        free(mode);
-        return;
-    }
-    if (!strcmp(mode, "on")) {
-        if (val != 6) {
-            usb_mode = 6;
-            sdb_sleep_ms(500);
-            if (vconf_set_int(DEBUG_MODE_KEY, 6)) {
-                D("Failed to set rndis %s\n", mode);
-                snprintf(buf, sizeof(buf), "Failed to set rndis %s\n", mode);
-                writex(fd, buf, strlen(buf));
-            }
-        }
-    } else if (!strcmp(mode, "off")) {
-        if (val != 2) {
-            usb_mode = 2;
-            sdb_sleep_ms(500);
-            if (vconf_set_int(DEBUG_MODE_KEY, 2)) {
-                D("Failed to set rndis %s\n", mode);
-                snprintf(buf, sizeof(buf), "Failed to set rndis %s\n", mode);
-                writex(fd, buf, strlen(buf));
-            }
-        }
-    } else {
-        D("Unknown command option:(rndis %s)\n", mode);
-        snprintf(buf, sizeof(buf), "Unknown command option:(rndis %s)\n", mode);
-        writex(fd, buf, strlen(buf));
-    }
-    free(mode);
-    sdb_close(fd);
-}
-
 #if 0
 static void echo_service(int fd, void *cookie)
 {
@@ -389,28 +391,28 @@ static void redirect_and_exec(int pts, const char *cmd, const char *argv[], cons
 
 static int create_subprocess(const char *cmd, pid_t *pid, const char *argv[], const char *envp[])
 {
-    char *devname;
+    char devname[64];
     int ptm;
 
     ptm = unix_open("/dev/ptmx", O_RDWR); // | O_NOCTTY);
     if(ptm < 0){
-        D("[ cannot open /dev/ptmx - %s ]\n",strerror(errno));
+        D("[ cannot open /dev/ptmx - errno:%d ]\n",errno);
         return -1;
     }
     if (fcntl(ptm, F_SETFD, FD_CLOEXEC) < 0) {
-        D("[ cannot set cloexec to /dev/ptmx - %s ]\n",strerror(errno));
+        D("[ cannot set cloexec to /dev/ptmx - errno:%d ]\n",errno);
     }
 
     if(grantpt(ptm) || unlockpt(ptm) ||
-       ((devname = (char*) ptsname(ptm)) == 0)){
-        D("[ trouble with /dev/ptmx - %s ]\n", strerror(errno));
+        ptsname_r(ptm, devname, sizeof(devname)) != 0 ){
+        D("[ trouble with /dev/ptmx - errno:%d ]\n", errno);
         sdb_close(ptm);
         return -1;
     }
 
     *pid = fork();
     if(*pid < 0) {
-        D("- fork failed: %s -\n", strerror(errno));
+        D("- fork failed: errno:%d -\n", errno);
         sdb_close(ptm);
         return -1;
     }
@@ -438,23 +440,62 @@ static int create_subprocess(const char *cmd, pid_t *pid, const char *argv[], co
                 sdb_close(fd);
             } else {
                // FIXME: not supposed to be here
-               D("sdb: unable to open %s due to %s\n", text, strerror(errno));
+               D("sdb: unable to open %s due to errno:%d\n", text, errno);
             }
         }
 
-        if (should_drop_privileges()) {
-            if (argv[2] != NULL && verify_root_commands(argv[2])) {
-                // do nothing
-                D("sdb: executes root commands!!:%s\n", argv[2]);
-            } else {
-                set_developer_privileges();
+        if (hostshell_mode == 1) {
+            if (should_drop_privileges()) {
+                if (argv[2] != NULL && getuid() == 0 && request_plugin_verification(SDBD_CMD_VERIFY_ROOTCMD, argv[2])) {
+                    // do nothing
+                    D("sdb: executes root commands!!:%s\n", argv[2]);
+                } else {
+                    set_developer_privileges();
+                }
             }
-        }
-
-        redirect_and_exec(pts, cmd, argv, envp);
-        fprintf(stderr, "- exec '%s' failed: (errno:%d) -\n",
-                cmd, errno);
-        exit(-1);
+                       redirect_and_exec(pts, cmd, argv, envp);
+               } else {
+                       char **pargv, **pargv_attach, sid[16];
+                       char *argv_attach[16] = {
+                          CMD_ATTACH,
+                          "-f",
+                          NULL,
+                       };
+                       pargv_attach = argv_attach + 2;
+
+                       if (should_drop_privileges()) {
+                               if (argv[2] != NULL && request_plugin_verification(SDBD_CMD_VERIFY_ROOTCMD, argv[2])) {
+                                       // do nothing
+                                       D("sdb: executes root commands!!:%s\n", argv[2]);
+                               } else {
+                                       snprintf(sid, 16, "%d", SID_DEVELOPER);
+                                       *(pargv_attach++) = "--uid";
+                                       *(pargv_attach++) = sid;
+                                       *(pargv_attach++) = "--gid";
+                                       *(pargv_attach++) = sid;
+
+                                       if (chdir("/home/developer") < 0) {
+                                               D("sdbd: unable to change working directory to /home/developer\n");
+                                       } else {
+                                               if (chdir("/") < 0) {
+                                                       D("sdbd: unable to change working directory to /\n");
+                                               }
+                                       }
+                                       // TODO: use pam later
+                                       //putenv("HOME=/home/developer");
+                                       setenv("HOME", "/home/developer", 1);
+                               }
+                       }
+                       *(pargv_attach++) = "--";
+                       pargv = argv;
+                       while(*pargv) {
+                               *(pargv_attach++) = *(pargv++);
+                       }
+                       redirect_and_exec(pts, CMD_ATTACH, argv_attach, envp);
+               }
+               fprintf(stderr, "- exec '%s' failed: (errno:%d) -\n",
+                       cmd, errno);
+               exit(-1);
     } else {
         // Don't set child's OOM adjustment to zero.
         // Let the child do it itself, as sometimes the parent starts
@@ -551,8 +592,9 @@ static int create_subproc_thread(const char *name, int lines, int columns)
     int ret_fd;
     pid_t pid;
     char *value = NULL;
-    char lines_str[20] = {'\0',};
-    char columns_str[20] = {'\0',};
+    char *trim_value = NULL;
+    char path[PATH_MAX];
+    memset(path, 0, sizeof(path));
 
     char *envp[] = {
         "TERM=linux", /* without this, some programs based on screen can't work, e.g. top */
@@ -563,40 +605,76 @@ static int create_subproc_thread(const char *name, int lines, int columns)
         NULL,
         NULL
     };
+
     if (should_drop_privileges()) {
-        envp[2] = "HOME=/home/developer";
-        get_env("ENV_PATH", &value);
-    } else {
-        get_env("ENV_SUPATH", &value);
-        envp[2] = "HOME=/root";
-    }
+         envp[2] = "HOME=/home/developer";
+         get_env("ENV_PATH", &value);
+     } else {
+         get_env("ENV_SUPATH", &value);
+         if(value == NULL) {
+             get_env("ENV_ROOTPATH", &value);
+         }
+         envp[2] = "HOME=/root";
+     }
     if (value != NULL) {
-        envp[3] = value;
+        trim_value = str_trim(value);
+        if (trim_value != NULL) {
+            // if string is not including 'PATH=', append it.
+            if (strncmp(trim_value, "PATH", 4)) {
+                snprintf(path, sizeof(path), "PATH=%s", trim_value);
+            } else {
+                snprintf(path, sizeof(path), "%s", trim_value);
+            }
+            envp[3] = path;
+            free(trim_value);
+        } else {
+            envp[3] = value;
+        }
     }
 
     D("path env:%s,%s,%s,%s\n", envp[0], envp[1], envp[2], envp[3]);
 
-    if (lines > 0 && columns > 0) {
-        snprintf(lines_str, sizeof(lines_str), "LINES=%d", lines);
-        snprintf(columns_str, sizeof(columns_str), "COLUMNS=%d", columns);
-        envp[4] = lines_str;
-        envp[5] = columns_str;
-        D("shell size env:%s,%s\n", envp[4], envp[5]);
-    }
-
     if(name) { // in case of shell execution directly
+        // Check the shell command validation.
+        if (!request_plugin_verification(SDBD_CMD_VERIFY_SHELLCMD, name)) {
+            D("This shell command is invalid. (%s)\n", name);
+            return -1;
+        }
+
+        // Convert the shell command.
+        char *new_cmd = NULL;
+        new_cmd = malloc(SDBD_SHELL_CMD_MAX);
+        if(new_cmd == NULL) {
+            D("Cannot allocate the shell commnad buffer.");
+            return -1;
+        }
+
+        memset(new_cmd, 0, SDBD_SHELL_CMD_MAX);
+        if(!request_plugin_cmd(SDBD_CMD_CONV_SHELLCMD, name, new_cmd, SDBD_SHELL_CMD_MAX)) {
+            D("Failed to convert the shell command. (%s)\n", name);
+            free(new_cmd);
+            return -1;
+        }
+
+        D("converted cmd : %s\n", new_cmd);
+
         char *args[] = {
             SHELL_COMMAND,
             "-c",
             NULL,
-            "-l",
-            SUPER_USER,
             NULL,
         };
-        args[2] = name;
+        args[2] = new_cmd;
 
         ret_fd = create_subprocess(SHELL_COMMAND, &pid, args, envp);
+        free(new_cmd);
     } else { // in case of shell interactively
+        // Check the capability for interactive shell support.
+        if (!is_support_interactive_shell()) {
+            D("This platform dose NOT support the interactive shell\n");
+            return -1;
+        }
+
         char *args[] = {
                 SHELL_COMMAND,
                 "-",
@@ -628,6 +706,18 @@ static int create_subproc_thread(const char *name, int lines, int columns)
         D("cannot create service thread\n");
         return -1;
     }
+
+    if (lines > 0 && columns > 0) {
+        D("shell size lines=%d, columns=%d\n", lines, columns);
+        struct winsize win_sz;
+        win_sz.ws_row = lines;
+        win_sz.ws_col = columns;
+
+        if (ioctl(ret_fd, TIOCSWINSZ, &win_sz) < 0) {
+            D("failed to sync window size.\n");
+        }
+    }
+
     sti = malloc(sizeof(stinfo));
     if(sti == 0) fatal("cannot allocate stinfo");
     sti->func = subproc_waiter_service;
@@ -667,7 +757,7 @@ static int create_sync_subprocess(void (*func)(int, void *), void* cookie) {
         //waitpid(pid, &ret, 0);
     }
     if (pid < 0) {
-        D("- fork failed: (errno:%d) -\n", errno);
+        D("- fork failed: errno:%d -\n", errno);
         sdb_close(s[0]);
         sdb_close(s[1]);
         D("cannot create sync service sub process\n");
@@ -711,25 +801,13 @@ static int create_syncproc_thread()
 
 #endif
 
-#define UNKNOWN "unknown"
-#define INFOBUF_MAXLEN 64
-#define INFO_VERSION "2.2.0"
-typedef struct platform_info {
-
-    char platform_info_version[INFOBUF_MAXLEN];
-    char model_name[INFOBUF_MAXLEN]; // Emulator
-    char platform_name[INFOBUF_MAXLEN]; // Tizen
-    char platform_version[INFOBUF_MAXLEN]; // 2.2.1
-    char profile_name[INFOBUF_MAXLEN]; // 2.2.1
-} pinfo;
-
 static void get_platforminfo(int fd, void *cookie) {
     pinfo sysinfo;
 
     char *value = NULL;
     s_strncpy(sysinfo.platform_info_version, INFO_VERSION, strlen(INFO_VERSION));
 
-    int r = system_info_get_value_string(SYSTEM_INFO_KEY_MODEL, &value);
+    int r = system_info_get_platform_string("http://tizen.org/system/model_name", &value);
     if (r != SYSTEM_INFO_ERROR_NONE) {
         s_strncpy(sysinfo.model_name, UNKNOWN, strlen(UNKNOWN));
         D("fail to get system model:%d\n", errno);
@@ -741,7 +819,7 @@ static void get_platforminfo(int fd, void *cookie) {
         }
     }
 
-    r = system_info_get_value_string(SYSTEM_INFO_KEY_PLATFORM_NAME, &value);
+    r = system_info_get_platform_string("http://tizen.org/system/platform.name", &value);
     if (r != SYSTEM_INFO_ERROR_NONE) {
         s_strncpy(sysinfo.platform_name, UNKNOWN, strlen(UNKNOWN));
         D("fail to get platform name:%d\n", errno);
@@ -784,6 +862,132 @@ static void get_platforminfo(int fd, void *cookie) {
     sdb_close(fd);
 }
 
+static int put_key_value_string(char* buf, int offset, int buf_size, char* key, char* value) {
+    int len = 0;
+    if ((len = snprintf(buf+offset, buf_size-offset, "%s:%s\n", key, value)) > 0) {
+        return len;
+    }
+    return 0;
+}
+
+static void get_capability(int fd, void *cookie) {
+    char cap_buffer[CAPBUF_SIZE] = {0,};
+    uint16_t offset = 0;
+
+    // Secure protocol support
+    offset += put_key_value_string(cap_buffer, offset, CAPBUF_SIZE,
+                                "secure_protocol", g_capabilities.secure_protocol);
+
+    // Interactive shell support
+    offset += put_key_value_string(cap_buffer, offset, CAPBUF_SIZE,
+                                "intershell_support", g_capabilities.intershell_support);
+
+    // File push/pull support
+    offset += put_key_value_string(cap_buffer, offset, CAPBUF_SIZE,
+                                "filesync_support", g_capabilities.filesync_support);
+
+    // USB protocol support
+    offset += put_key_value_string(cap_buffer, offset, CAPBUF_SIZE,
+                                "usbproto_support", g_capabilities.usbproto_support);
+
+    // Socket protocol support
+    offset += put_key_value_string(cap_buffer, offset, CAPBUF_SIZE,
+                                "sockproto_support", g_capabilities.sockproto_support);
+
+    // Root command support
+    offset += put_key_value_string(cap_buffer, offset, CAPBUF_SIZE,
+                                "rootonoff_support", g_capabilities.rootonoff_support);
+
+    // Zone support
+    offset += put_key_value_string(cap_buffer, offset, CAPBUF_SIZE,
+                                "zone_support", g_capabilities.zone_support);
+
+    // Multi-User support
+    offset += put_key_value_string(cap_buffer, offset, CAPBUF_SIZE,
+                                "multiuser_support", g_capabilities.multiuser_support);
+
+    // CPU Architecture of model
+    offset += put_key_value_string(cap_buffer, offset, CAPBUF_SIZE,
+                                "cpu_arch", g_capabilities.cpu_arch);
+
+    // Profile name
+    offset += put_key_value_string(cap_buffer, offset, CAPBUF_SIZE,
+                                "profile_name", g_capabilities.profile_name);
+
+    // Vendor name
+    offset += put_key_value_string(cap_buffer, offset, CAPBUF_SIZE,
+                                "vendor_name", g_capabilities.vendor_name);
+
+    // Platform version
+    offset += put_key_value_string(cap_buffer, offset, CAPBUF_SIZE,
+                                "platform_version", g_capabilities.platform_version);
+
+    // Product version
+    offset += put_key_value_string(cap_buffer, offset, CAPBUF_SIZE,
+                                "product_version", g_capabilities.product_version);
+
+    // Sdbd version
+    offset += put_key_value_string(cap_buffer, offset, CAPBUF_SIZE,
+                                "sdbd_version", g_capabilities.sdbd_version);
+
+    // Sdbd plugin version
+    offset += put_key_value_string(cap_buffer, offset, CAPBUF_SIZE,
+                                "sdbd_plugin_version", g_capabilities.sdbd_plugin_version);
+
+    // Window size synchronization support
+    offset += put_key_value_string(cap_buffer, offset, CAPBUF_SIZE,
+                                "syncwinsz_support", g_capabilities.syncwinsz_support);
+
+
+    offset++; // for '\0' character
+
+    writex(fd, &offset, sizeof(uint16_t));
+    writex(fd, cap_buffer, offset);
+
+    sdb_close(fd);
+}
+
+static void sync_windowsize(int fd, void *cookie) {
+    int id, lines, columns;
+    char *size_info = cookie;
+    asocket *s = NULL;
+
+    if (sscanf(size_info, "%d:%d:%d", &id, &lines, &columns) == 3) {
+        D("window size information: id=%d, lines=%d, columns=%d\n", id, lines, columns);
+    }
+    if((s = find_local_socket(id))) {
+        struct winsize win_sz;
+        win_sz.ws_row = lines;
+        win_sz.ws_col = columns;
+
+        if (ioctl(s->fd, TIOCSWINSZ, &win_sz) < 0) {
+            D("failed to sync window size.\n");
+            return;
+        }
+        D("success to sync window size.\n");
+    }
+}
+
+const unsigned COMMAND_TIMEOUT = 10000;
+void get_boot(int fd, void *cookie) {
+    char buf[2] = { 0, };
+    char *mode = (char*) cookie;
+    int time = 0;
+    int interval = 1000;
+    while (time < COMMAND_TIMEOUT) {
+        if (booting_done == 1) {
+            D("get_boot:platform booting is done\n");
+            snprintf(buf, sizeof(buf), "%s", "1");
+            break;
+        }
+        D("get_boot:platform booting is in progress\n");
+        sdb_sleep_ms(interval);
+        time += interval;
+    }
+    writex(fd, buf, strlen(buf));
+    sdb_close(fd);
+}
+
 int service_to_fd(const char *name)
 {
     int ret = -1;
@@ -806,9 +1010,7 @@ int service_to_fd(const char *name)
                 ret = socket_loopback_client(port, SOCK_STREAM);
             }
             if (ret >= 0) {
-                if (disable_tcp_nagle(ret) < 0) {
-                    D("failed to disable_tcp_nagle\n");
-                }
+                disable_tcp_nagle(ret);
             }
         } else {
 #if SDB_HOST
@@ -887,12 +1089,18 @@ int service_to_fd(const char *name)
 #endif
     } else if(!strncmp(name, "sysinfo:", 8)){
         ret = create_service_thread(get_platforminfo, 0);
-    } else if(!strncmp(name, "rndis:", 6)){
-        char *service_name = NULL;
-
-        service_name = strdup(name+6);
-        ret = create_service_thread(rndis_config_service, (void *)(service_name));
+    } else if(!strncmp(name, "capability:", 11)){
+        ret = create_service_thread(get_capability, 0);
+    } else if(!strncmp(name, "boot:", 5)){
+        if (is_emulator()) {
+            ret = create_service_thread(get_boot, 0);
+        }
+    } else if(!strncmp(name, "shellconf:", 10)){
+        if(!strncmp(name+10, "syncwinsz:", 10)){
+            ret = create_service_thread(sync_windowsize, name+20);
+        }
     }
+
     if (ret >= 0) {
         if (close_on_exec(ret) < 0) {
             D("failed to close fd exec\n");
index a25307b..e2559cf 100644 (file)
 #endif
 
 #include "strutils.h"
+extern int hostshell_mode;
 /* Connect to port on the loopback IP interface. type is
  * SOCK_STREAM or SOCK_DGRAM. 
  * return is a file descriptor or -1 on error
  */
 int socket_loopback_client(int port, int type)
 {
+    char zone_ipaddr[1025] = {0, };
+    char name_vsm[1025] = {0, };
+    int namelen;
     struct sockaddr_in addr;
     int s;
 
     memset(&addr, 0, sizeof(addr));
     addr.sin_family = AF_INET;
     addr.sin_port = htons(port);
-    addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+
+    if (hostshell_mode == 0) {
+        FILE *fp;
+        fp = popen("/usr/bin/vsm-foreground", "r");
+        if (fp == NULL) {
+            return 0;
+        }
+        fgets(name_vsm, 1025, fp);
+        pclose(fp);
+
+        snprintf(zone_ipaddr, 1025, "/usr/bin/vsm-info -i -n %s", name_vsm);
+        fp = popen(zone_ipaddr, "r");
+        if (fp == NULL) {
+            return 0;
+        }
+        fgets(zone_ipaddr, 1025, fp);
+        pclose(fp);
+
+        //trim zone ipaddr
+        namelen = strlen(zone_ipaddr);
+        while (zone_ipaddr[--namelen] == '\n')
+            ;
+        zone_ipaddr[namelen + 1] = '\0';
+
+        addr.sin_addr.s_addr = inet_addr(zone_ipaddr);
+    } else {
+        addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+    }
 
     s = socket(AF_INET, type, 0);
     if(s < 0) return -1;
@@ -81,7 +112,9 @@ int socket_ifr_client(int port, int type, char *ifr_dev)
         return -1;
     }
 
-    addr.sin_addr.s_addr = inet_addr(inet_ntoa(((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr));
+    char buf[1025] = {0, };
+    inet_ntop(AF_INET, &((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr, buf, sizeof(buf));
+    addr.sin_addr.s_addr = inet_addr(buf);
 
     close(s);
 
@@ -138,7 +171,7 @@ int ifconfig(char *ifname, char *address, char *netmask, int activated) {
         ifr.ifr_flags |= ~IFF_UP;
     }
     if (ioctl(sockfd, SIOCGIFFLAGS, &ifr) < 0) {
-        fprintf(stderr,"cannot set SIOCGIFFLAGS flags: (errno:%d)\n", errno);
+        fprintf(stderr,"cannot set SIOCGIFFLAGS flags: errno:%d\n", errno);
         close(sockfd);
         return -1;
     }
index 1c0b23b..5018ef7 100644 (file)
@@ -16,7 +16,7 @@
 // libs/cutils/socket_network_client.c
 
 #include "sockets.h"
-#include <stdio.h>
+
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
@@ -47,8 +47,7 @@ int socket_network_client(const char *host, int port, int type)
 
     tmphstbuf = malloc(hstbuflen);
     if (tmphstbuf == NULL) {
-        fprintf(stderr, "out of memory\n");
-        exit(-1);
+        return -1;
     }
 
     while ((res = gethostbyname_r(host, &hostbuf, tmphstbuf, hstbuflen, &hp, &herr)) == ERANGE) {
@@ -56,8 +55,7 @@ int socket_network_client(const char *host, int port, int type)
         hstbuflen *= 2;
         tmphstbuf = realloc(tmphstbuf, hstbuflen);
         if (tmphstbuf == NULL) {
-            fprintf(stderr, "out of memory\n");
-            exit(-1);
+            return -1;
         }
     }
     if (res || hp == NULL) {
@@ -93,3 +91,4 @@ int socket_network_client(const char *host, int port, int type)
     return s;
 
 }
+
index 629d56d..16e746e 100644 (file)
@@ -200,7 +200,6 @@ static void local_socket_close(asocket *s)
 static void local_socket_destroy(asocket  *s)
 {
     apacket *p, *n;
-    int exit_on_close = s->exit_on_close;
 
     D("LS(%d): destroying fde.fd=%d\n", s->id, s->fde.fd);
 
@@ -217,11 +216,6 @@ static void local_socket_destroy(asocket  *s)
     }
     remove_socket(s);
     free(s);
-
-    if (exit_on_close) {
-        D("local_socket_destroy: exiting\n");
-        exit(1);
-    }
 }
 
 
@@ -429,15 +423,6 @@ asocket *create_local_service_socket(const char *name)
     s = create_local_socket(fd);
     D("LS(%d): bound to '%s' via %d\n", s->id, name, fd);
 
-#if !SDB_HOST
-    if ((!strncmp(name, "root:", 5) && getuid() != 0)
-        || !strncmp(name, "usb:", 4)
-        || !strncmp(name, "tcpip:", 6)) {
-        D("LS(%d): enabling exit_on_close\n", s->id);
-        s->exit_on_close = 1;
-    }
-#endif
-
     return s;
 }
 
index edbb2c9..a72e798 100644 (file)
@@ -292,6 +292,7 @@ static __inline__  int  sdb_is_absolute_host_path( const char*  path )
 #include <netinet/in.h>
 #include <netinet/tcp.h>
 #include <string.h>
+#include <time.h>
 
 #define OS_PATH_SEPARATOR '/'
 #define OS_PATH_SEPARATOR_STR "/"
@@ -462,13 +463,10 @@ static __inline__  int  sdb_socket_setbufsize( int   fd, int  bufsize )
     return setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &opt, sizeof(opt));
 }
 
-static __inline__ int  disable_tcp_nagle(int fd)
+static __inline__ void  disable_tcp_nagle(int fd)
 {
-    int on = 1;
-    if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (void*) &on, sizeof(on)) < 0) {
-        return -1;
-    }
-    return 0;
+    int  on = 1;
+    setsockopt( fd, IPPROTO_TCP, TCP_NODELAY, (void*)&on, sizeof(on) );
 }
 
 
@@ -500,7 +498,10 @@ static __inline__ int  sdb_socketpair( int  sv[2] )
 
 static __inline__ void  sdb_sleep_ms( int  mseconds )
 {
-    usleep( mseconds*1000 );
+    struct timespec ts;
+    ts.tv_sec = mseconds / 1000;
+    ts.tv_nsec = (mseconds % 1000) * 1000000;
+    nanosleep(&ts, NULL);
 }
 
 static __inline__ int  sdb_mkdir(const char*  path, int mode)
index 6f32b9d..e63e5d6 100644 (file)
@@ -889,7 +889,7 @@ void register_socket_transport(int s, const char *serial, int port, int local, c
 {
     atransport *t = calloc(1, sizeof(atransport));
     if (t == NULL) {
-        D("could not allocate atransport'\n");
+        D("failed to allocate memory of transport struct\n");
         return;
     }
     char buff[32];
@@ -1020,12 +1020,12 @@ void broadcast_transport(apacket *p)
 
 void register_usb_transport(usb_handle *usb, const char *serial, unsigned writeable)
 {
+    char device_name[256];
     atransport *t = calloc(1, sizeof(atransport));
     if (t == NULL) {
-        D("cannot allocate atransport");
+        D("failed to allocate memory of transport struct\n");
         return;
     }
-    char device_name[256];
 
     D("transport: %p init'ing for usb_handle %p (sn='%s')\n", t, usb,
       serial ? serial : "");
@@ -1073,7 +1073,7 @@ int readx(int fd, void *ptr, size_t len)
             p += r;
         } else {
             if (r < 0) {
-                D("readx: fd=%d (errno:%d)\n", fd, errno);
+                D("readx: fd=%d error %d\n", fd, errno);
                 if (errno == EINTR)
                     continue;
             } else {
index 67a0887..2095b8e 100644 (file)
@@ -139,9 +139,7 @@ int local_connect_arbitrary_ports(int console_port, int sdb_port, const char *de
         if (close_on_exec(fd) < 0) {
             D("failed to close fd exec\n");
         }
-        if (disable_tcp_nagle(fd) < 0) {
-            D("failed to disable_tcp_nagle\n");
-        }
+        disable_tcp_nagle(fd);
         snprintf(buf, sizeof buf, "%s%d", LOCAL_CLIENT_PREFIX, console_port);
         register_socket_transport(fd, buf, sdb_port, 1, device_name);
         return 0;
@@ -165,7 +163,7 @@ int get_devicename_from_shdmem(int port, char *device_name)
 
     if (shared_memory == (void *)-1)
     {
-        D("faild to get shdmem key (%d) : %s\n", port, strerror(errno));
+        D("faild to get shdmem key (%d) : errno:%d\n", port, errno);
         return -1;
     }
 
@@ -251,7 +249,7 @@ static void *client_socket_thread(void *x)
 static void *server_socket_thread(void * arg)
 {
     int serverfd, fd;
-    struct sockaddr addr;
+    struct sockaddr_in addr;
     socklen_t alen;
     int port = (int)arg;
 
@@ -279,16 +277,21 @@ static void *server_socket_thread(void * arg)
             pthread_cond_broadcast(&noti_cond);
         }
 
-        fd = sdb_socket_accept(serverfd, &addr, &alen);
+        fd = sdb_socket_accept(serverfd, (struct sockaddr *)&addr, &alen);
         if(fd >= 0) {
             D("server: new connection on fd %d\n", fd);
             if (close_on_exec(fd) < 0) {
                 D("failed to close fd exec\n");
             }
-            if (disable_tcp_nagle(fd) < 0) {
-                D("failed to disable_tcp_nagle\n");
+            disable_tcp_nagle(fd);
+
+            // Check the peer ip validation.
+            if (!is_emulator()
+                && !request_plugin_verification(SDBD_CMD_VERIFY_PEERIP, inet_ntoa(addr.sin_addr))) {
+                sdb_close(fd);
+            } else {
+                register_socket_transport(fd, "host", port, 1, NULL);
             }
-            register_socket_transport(fd, "host", port, 1, NULL);
         }
     }
     D("transport: server_socket_thread() exiting\n");
@@ -417,8 +420,8 @@ int connect_nonb(int sockfd, const struct sockaddr *saptr, socklen_t salen,
 
     flags = fcntl(sockfd, F_GETFL, 0);
     if(fcntl(sockfd, F_SETFL, flags | O_NONBLOCK) == -1) {
-        D("failed to set file O_NONBLOCK status flag for socket %d: %s\n",
-                     sockfd, strerror(errno));
+        D("failed to set file O_NONBLOCK status flag for socket %d: errno:%d\n",
+                     sockfd, errno);
     }
 
     error = 0;
@@ -452,8 +455,8 @@ int connect_nonb(int sockfd, const struct sockaddr *saptr, socklen_t salen,
 
     done:
     if(fcntl(sockfd, F_SETFL, flags) == -1) { /* restore file status flags */
-        D("failed to restore file status flag for socket %d: (errno:%d)\n",
-                 sockfd, errno);
+        D("failed to restore file status flag for socket %d\n",
+                 sockfd);
     }
 
     if (error) {
@@ -464,16 +467,16 @@ int connect_nonb(int sockfd, const struct sockaddr *saptr, socklen_t salen,
     return (0);
 }
 
-static int send_msg_to_localhost_from_guest(int local_port, char *request, int sock_type) {
+static int send_msg_to_localhost_from_guest(const char *host_ip, int local_port, char *request, int sock_type) {
     int                  ret, s;
     struct sockaddr_in   server;
     int connect_timeout = 1;
     memset( &server, 0, sizeof(server) );
     server.sin_family      = AF_INET;
     server.sin_port        = htons(local_port);
-    server.sin_addr.s_addr = inet_addr(QEMU_FORWARD_IP);
+    server.sin_addr.s_addr = inet_addr(host_ip);
 
-    D("try to send notification to host(%s:%d) using %s:[%s]\n", QEMU_FORWARD_IP, local_port, (sock_type == 0) ? "tcp" : "udp", request);
+    D("try to send notification to host(%s:%d) using %s:[%s]\n", host_ip, local_port, (sock_type == 0) ? "tcp" : "udp", request);
 
     if (sock_type == 0) {
         s = socket(AF_INET, SOCK_STREAM, 0);
@@ -490,7 +493,6 @@ static int send_msg_to_localhost_from_guest(int local_port, char *request, int s
         sdb_close(s);
         return -1;
     }
-    // writex handles EINTR and returns 0 if success
     if (writex(s, request, strlen(request)) != 0) {
         D("could not send notification request to host\n");
         sdb_close(s);
@@ -502,6 +504,7 @@ static int send_msg_to_localhost_from_guest(int local_port, char *request, int s
     return 0;
 }
 
+/*
 static void notify_sdbd_startup() {
     char                 buffer[512];
     char                 request[512];
@@ -538,6 +541,7 @@ static void notify_sdbd_startup() {
         sleep(1);
     }
 }
+*/
 
 // send the "emulator" request to sdbserver
 static void notify_sdbd_startup_thread() {
@@ -545,52 +549,60 @@ static void notify_sdbd_startup_thread() {
     char                 request[512];
 
     char vm_name[256]={0,};
+    char host_ip[256] = {0,};
+    char guest_ip[256] = {0,};
     int base_port = get_emulator_forward_port();
     int r = get_emulator_name(vm_name, sizeof vm_name);
     int time = 0;
-    int try_limit_time = -1; // try_limit_time < 0 if unlimited
+    //int try_limit_time = -1; // try_limit_time < 0 if unlimited
     if (base_port < 0 || r < 0) {
         return;
     }
-
+    if (get_emulator_hostip(host_ip, sizeof host_ip) == -1) {
+       D("failed to get emulator host ip\n");
+       return;
+    }
     // XXX: Known issue - log collision
     while (1) {
-        /* XXX: Known issue - timing issue
-        A request failure can happen at the starting up of a SDB server
-        (with very little probability)
-        If a SDB server establish a new connection and send a request
-        between D1 and D2, the request will fail.
-        Becuase when a SDB server gets a duplicated "emulator:" command,
-        it closes the existing transport connection.
-        */
-
-        // If there is any connected (via TCP/IP) SDB server, sleep 10 secs (D1)
+        // Trial limitation reached. terminate notify thread.
+        /*if (0 <= try_limit_time && try_limit_time <= time) {
+            break;
+        }*/
+        // If there is any connected (via TCP/IP) SDB server, sleep 10 secs
         if (get_connected_count(kTransportLocal) > 0) {
             if (time >= 0) {
                 time = 0;
-                D("notify_sdbd_startup() success after %d trial(s)", time);
+                D("notify_sdbd_startup() success after %d trial(s)\n", time);
             }
             sleep(10);
             continue;
         }
 
+        if (get_emulator_guestip(guest_ip, sizeof guest_ip) == -1) {
+                       D("failed to get emulator guest ip\n");
+                       goto sleep_and_continue;
+               }
+
         // tell qemu sdbd is just started with udp
-        if (send_msg_to_localhost_from_guest(base_port + 3, "2\n", 1) < 0) {
+        if (send_msg_to_localhost_from_guest(host_ip, base_port + 3, "2\n", 1) < 0) {
             D("could not send sensord noti request, try again %dth\n", time+1);
             goto sleep_and_continue;
         }
 
-        // tell sdb server emulator's vms name (D2)
-        snprintf(request, sizeof request, "host:emulator:%d:%s",base_port + 1, vm_name);
-        snprintf(buffer, sizeof buffer, "%04x%s", strlen(request), request );
+        // tell sdb server emulator's vms name
+        // TODO: should we use host:emulator request? let's talk about this!
 
-        if (get_connected_count(kTransportLocal) > 0) continue; // See comment above
+        if (!strncmp(host_ip, QEMU_FORWARD_IP, sizeof host_ip)) {
+            snprintf(request, sizeof request, "host:emulator:%d:%s",base_port + 1, vm_name);
+        } else {
+            snprintf(request, sizeof request, "host:connect:%s:%d", guest_ip, DEFAULT_SDB_LOCAL_TRANSPORT_PORT);
+        }
+        snprintf(buffer, sizeof buffer, "%04x%s", strlen(request), request );
 
-        if (send_msg_to_localhost_from_guest(DEFAULT_SDB_PORT, buffer, 0) <0) {
+        if (send_msg_to_localhost_from_guest(host_ip, DEFAULT_SDB_PORT, buffer, 0) <0) {
             D("could not send sdbd noti request. it might sdb server has not been started yet.\n");
             goto sleep_and_continue;
         }
-        
         //LOGI("sdbd noti request sent.\n");
 
 sleep_and_continue:
@@ -645,7 +657,7 @@ void local_init(int port)
         // thread start
         if(sdb_thread_create(&thr, notify_sdbd_startup_thread, NULL)) {
             fatal("cannot create notify_sdbd_startup_thread");
-            notify_sdbd_startup(); // defensive code
+            //notify_sdbd_startup(); // defensive code
         }
         sdb_mutex_unlock(&register_noti_lock);
     }
index cd72c07..d7e8399 100644 (file)
@@ -437,8 +437,8 @@ int usb_write(usb_handle *h, const void *_data, int len)
 
         n = usb_bulk_write(h, data, xfer);
         if(n != xfer) {
-            D("ERROR: n = %d, errno = %d (%s)\n",
-                n, errno, strerror(errno));
+            D("ERROR: n = %d, errno = %d\n",
+                n, errno);
             return -1;
         }
 
@@ -475,8 +475,8 @@ int usb_read(usb_handle *h, void *_data, int len)
                 }
                 continue;
             }
-            D("ERROR: n = %d, errno = %d (%s)\n",
-                n, errno, strerror(errno));
+            D("ERROR: n = %d, errno = %d \n",
+                n, errno);
             return -1;
         }
 
@@ -672,8 +672,8 @@ static void register_device(const char *dev_name,
     return;
 
 fail:
-    D("[ usb open %s error=%d, err_str = %s]\n",
-        usb->fname,  errno, strerror(errno));
+    D("[ usb open %s error=%d]\n",
+        usb->fname,  errno);
     if(usb->desc >= 0) {
         sdb_close(usb->desc);
     }
index db7ca9a..c7ac0d8 100644 (file)
@@ -97,7 +97,7 @@ int usb_write(usb_handle *h, const void *data, int len)
     return 0;
 }
 
-int usb_read(usb_handle *h, void *data, int len)
+int usb_read(usb_handle *h, void *data, unsigned len)
 {
     int n;
 
@@ -120,9 +120,10 @@ void usb_init()
 
     h = calloc(1, sizeof(usb_handle));
     if (h == NULL) {
-        D("cannot allocate usb handle");
+        D("failed to allocate memory of usb_handle\n");
         return;
     }
+
     h->fd = -1;
     sdb_cond_init(&h->notify, 0);
     sdb_mutex_init(&h->lock, 0);
index 589f86f..b111a16 100644 (file)
@@ -124,8 +124,7 @@ char *str_trim(const char* string)
         e--;
 
     ret = strdup(s);
-    if (ret == NULL) {
-        fprintf(stderr, "failed to strdup");
+    if(ret == NULL) {
         return NULL;
     }
     ret[e - s + 1] = 0;
@@ -160,3 +159,47 @@ int spawn(char* program, char** arg_list)
     return pid;
 }
 
+char** str_split(char* a_str, const char a_delim) {
+       char** result = 0;
+       size_t count = 0;
+       char* tmp = a_str;
+       char* last_comma = 0;
+       char delim[2];
+       delim[0] = a_delim;
+       delim[1] = 0;
+       char *ptr;
+
+       /* Count how many elements will be extracted. */
+       while (*tmp) {
+               if (a_delim == *tmp) {
+                       count++;
+                       last_comma = tmp;
+               }
+               tmp++;
+       }
+
+       /* Add space for trailing token. */
+       count += last_comma < (a_str + strlen(a_str) - 1);
+
+       /* Add space for terminating null string so caller
+        knows where the list of returned strings ends. */
+       count++;
+
+       result = malloc(sizeof(char*) * count);
+
+       if (result) {
+               size_t idx = 0;
+               char* token = strtok_r(a_str, delim, &ptr);
+
+               while (token) {
+                       //assert(idx < count);
+                       *(result + idx++) = strdup(token);
+                       token = strtok_r(0, delim, &ptr);
+               }
+               //assert(idx == count - 1);
+               *(result + idx) = 0;
+       }
+
+       return result;
+}
+
index bc228d4..9dcee82 100644 (file)
@@ -74,4 +74,6 @@ char *str_trim(const char* string);
  */
 int spawn(char* program, char** arg_list);
 
+char** str_split(char* a_str, const char a_delim);
+
 #endif /* _SDB_UTILS_H */