Merge branch 'tizen_2.4_merge' into tizen 11/56311/2
authorKim Gunsoo <gunsoo83.kim@samsung.com>
Wed, 6 Jan 2016 08:29:02 +0000 (17:29 +0900)
committershingil.kang <shingil.kang@samsung.com>
Fri, 8 Jan 2016 10:14:52 +0000 (19:14 +0900)
Change-Id: Iff477f5ca164496b2ab6144f35195ffeb7dbcbdc
Signed-off-by: Kim Gunsoo <gunsoo83.kim@samsung.com>
40 files changed:
CMakeLists.txt
debian/changelog [new file with mode: 0644]
debian/compat [new file with mode: 0644]
debian/control [new file with mode: 0644]
debian/rules [new file with mode: 0755]
debian/sdbd.install [new file with mode: 0644]
packaging/sdbd.changes
packaging/sdbd.service [new file with mode: 0644]
packaging/sdbd.spec
packaging/sdbd_device.service
packaging/sdbd_emulator.service
script/profile_command [new file with mode: 0755]
script/sdk_launch
sdbd.manifest [new file with mode: 0644]
src/commandline.c
src/commandline_sdbd.c
src/file_sync_client.c
src/file_sync_service.c
src/file_sync_service.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_local_client.c
src/socket_loopback_client.c
src/socket_network_client.c
src/sockets.c
src/sockets.h
src/strutils.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

index 95e9b08..f160f95 100644 (file)
@@ -19,7 +19,14 @@ project (sdbd)
 option(USE_FUNCTION_FS "Use FunctionFS" NO)
 option(BUILD_UNIT_TESTS "Build unit tests" NO)
 
-set(sdbd_SRCS
+
+############################# cmake packages ##################################
+
+INCLUDE(FindPkgConfig)
+
+############################# compiler flags ##################################
+
+SET(SDBD_SRCS
        src/sdb.c
        src/fdevent.c
        src/transport.c
@@ -28,6 +35,7 @@ set(sdbd_SRCS
        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
@@ -45,9 +53,51 @@ set(sdbd_SRCS
        src/usb_funcfs_client.c
 )
 
-include_directories(src)
+include(FindPkgConfig)
+
+pkg_check_modules(pkgs REQUIRED
+    libtzplatform-config
+    capi-system-info
+    vconf
+    glib-2.0
+    dbus-1
+    dbus-glib-1
+ )
+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})
+ADD_EXECUTABLE(sdbd ${SDBD_SRCS})
+TARGET_LINK_LIBRARIES(sdbd -pie -lsmack -lresolv -ldl ${CMAKE_THREAD_LIBS_INIT} ${pkgs_LDFLAGS})
 
 set_property(
        TARGET sdbd
@@ -73,20 +123,6 @@ if(USE_FUNCTION_FS)
        )
 endif()
 
-ADD_DEFINITIONS("-fPIE")
-
-include(FindPkgConfig)
-
-# Get capi-system-info
-pkg_check_modules(CAPI_SYSTEM_INFO REQUIRED capi-system-info libtzplatform-config)
-include_directories(${CAPI_SYSTEM_INFO_INCLUDE_DIRS})
-
-# Get pthreads
-find_package(Threads REQUIRED)
-
-# Add libraries (-l...)
-target_link_libraries (sdbd -pie -lsmack ${CMAKE_THREAD_LIBS_INIT} ${CAPI_SYSTEM_INFO_LDFLAGS})
-
 install(TARGETS sdbd DESTINATION /usr/sbin)
 install(FILES script/sdbd DESTINATION /etc/init.d)
 
diff --git a/debian/changelog b/debian/changelog
new file mode 100644 (file)
index 0000000..898caea
--- /dev/null
@@ -0,0 +1,129 @@
+sdbd (0.0.2-2) unstable; urgency=low
+
+  * set dir permission to 777
+  * Git: slp/pkgs/s/sdbd
+  * Tag: sdbd_0.0.2-2
+
+ -- Yoonki Park <yoonki.park@samsung.com>  Wed, 18 Apr 2012 16:57:03 +0900
+
+sdbd (0.0.2-1) unstable; urgency=low
+
+  * let sshd be daemon and create sshd.pid file
+  * Git: slp/pkgs/s/sdbd
+  * Tag: sdbd_0.0.2-1
+
+ -- Yoonki Park <yoonki.park@samsung.com>  Mon, 02 Apr 2012 14:37:44 +0900
+
+sdbd (0.0.2) unstable; urgency=low
+
+  * add rpm spec file
+  * Git: slp/pkgs/s/sdbd
+  * Tag: sdbd_0.0.2
+
+ -- Yoonki Park <yoonki.park@samsung.com>  Mon, 19 Mar 2012 17:03:59 +0900
+
+sdbd (0.0.1-13) unstable; urgency=low
+
+  * let start_device_log enable, update maintainer information and set process working directory path to '/'
+  * Git: slp/pkgs/s/sdbd
+  * Tag: sdbd_0.0.1-13
+
+ -- Yoonki Park <yoonki.park@samsung.com>  Wed, 14 Mar 2012 17:06:36 +0900
+
+sdbd (0.0.1-12) unstable; urgency=low
+
+  * update changlog file according to package policy  
+  * Git: slp/pkgs/s/sdbd
+  * Tag: sdbd_0.0.1-12
+
+ -- Yoonki Park <yoonki.park@samsung.com>  Mon, 05 Mar 2012 10:48:47 +0900
+
+sdbd (0.0.1-11) unstable; urgency=low
+
+  * add loopback interface checking when binding to 26099
+  * Git: pkgs/s/sdbd
+  * Tag: sdbd_0.0.1-11
+
+ -- Yoonki Park <yoonki.park@samsung.com>  Wed, 29 Feb 2012 21:09:37 +0900
+
+sdbd (0.0.1-10) unstable; urgency=low
+
+  * Add SIGTERM handler for avoid terminate on the emulator
+  * Git: 165.213.180.234:slp/pkgs/s/sdbd
+  * Tag: sdbd_0.0.1-10
+
+ -- Joogwan Kim <joogwan.kim@samsung.com>  Tue, 13 Dec 2011 21:26:01 +0900
+
+sdbd (0.0.1-9) unstable; urgency=low
+
+  * Remove unused files
+  * Git: 165.213.180.234:slp/pkgs/s/sdbd
+  * Tag: sdbd_0.0.1-9
+
+ -- Joogwan Kim <joogwan.kim@samsung.com>  Tue, 06 Dec 2011 18:59:38 +0900
+
+sdbd (0.0.1-8) unstable; urgency=low
+
+  * Modify script name to get higher priority
+  * Git: 165.213.180.234:slp/pkgs/s/sdbd
+  * Tag: sdbd_0.0.1-8 
+
+ -- Joogwan Kim <joogwan.kim@samsung.com>  Fri, 11 Nov 2011 16:29:46 +0900
+
+sdbd (0.0.1-7) unstable; urgency=low
+
+  * Upload missing files from 0.0.1-6
+  * Git: 165.213.180.234:slp/pkgs/s/sdbd
+  * Tag: sdbd_0.0.1-7 
+
+ -- Jinhyung Choi <jinhyung2.choi@samsung.com>  Thu, 13 Oct 2011 22:19:19 +0900
+
+sdbd (0.0.1-6) unstable; urgency=low
+
+  * Supports multi configuration on linux
+  * Change name from Android debug bridge to Samsung Development Bridge in status_window function
+  * Git: 165.213.180.234:slp/pkgs/s/sdbd
+  * Tag: sdbd_0.0.1-6 
+
+ -- Jinhyung Choi <jinhyung2.choi@samsung.com>  Thu, 13 Oct 2011 21:22:03 +0900
+
+sdbd (0.0.1-5) unstable; urgency=low
+
+  * Modify dev name from android_adb to samsung_sdb
+  * Git: 165.213.180.234:slp/pkgs/s/sdbd
+  * Tag: sdbd_0.0.1-5 
+
+ -- Joogwan Kim <joogwan.kim@samsung.com>  Tue, 11 Oct 2011 22:52:33 +0900
+
+sdbd (0.0.1-4) unstable; urgency=low
+
+  * Change name from android_adb to samsung_sdb and removed unused
+  * Change sdb interface descriptor
+  * Git: 165.213.180.234:slp/pkgs/s/sdbd
+  * Tag: sdbd_0.0.1-4 
+
+ -- Joogwan Kim <joogwan.kim@samsung.com>  Tue, 11 Oct 2011 14:35:55 +0900
+
+sdbd (0.0.1-3) unstable; urgency=low
+
+  * Just version up for upload
+  * Git: 165.213.180.234:slp/pkgs/s/sdbd
+  * Tag: sdbd_0.0.1-3
+
+ -- Joogwan Kim <joogwan.kim@samsung.com>  Mon, 10 Oct 2011 16:49:02 +0900
+
+sdbd (0.0.1-2) unstable; urgency=low
+
+  * Just version up for upload source package 
+  * Git: 165.213.180.234:slp/pkgs/s/sdbd
+  * Tag: sdbd_0.0.1-2
+
+ -- Joogwan Kim <joogwan.kim@samsung.com>  Mon, 10 Oct 2011 16:28:41 +0900
+
+sdbd (0.0.1-1) unstable; urgency=low
+
+  * Initial upload
+  * Git: 165.213.180.234:slp/pkgs/s/sdbd
+  * Tag: sdbd_0.0.1-1
+
+ -- Joogwan Kim <joogwan.kim@samsung.com>  Sat, 26 Sep 2011 15:00:56 +0900
diff --git a/debian/compat b/debian/compat
new file mode 100644 (file)
index 0000000..7813681
--- /dev/null
@@ -0,0 +1 @@
+5
\ No newline at end of file
diff --git a/debian/control b/debian/control
new file mode 100644 (file)
index 0000000..aa3ba16
--- /dev/null
@@ -0,0 +1,10 @@
+Source: sdbd
+Section: net
+Priority: extra
+Maintainer: Kangho Kim <kh5325.kim@samsung.com>, Yoonki Park <yoonki.park@samsung.com>, Ho Namkoong <ho.namkoong@samsung.com> 
+Build-Depends: debhelper (>= 5), libc6-dev
+Standards-Version: 0.0.1
+
+Package: sdbd
+Architecture: any 
+Description: SDB daemon
diff --git a/debian/rules b/debian/rules
new file mode 100755 (executable)
index 0000000..6ebe31f
--- /dev/null
@@ -0,0 +1,44 @@
+#!/usr/bin/make -f
+
+UNAME := $(shell uname -sm)
+ifneq (,$(findstring 86,$(UNAME)))
+       HOST_ARCH := x86
+endif
+
+configure: configure-stamp
+
+configure-stamp:
+       dh_testdir
+       touch configure-stamp
+
+build: build-stamp
+
+build-stamp: configure-stamp
+       dh_testdir
+       $(MAKE)
+       touch build-stamp
+
+install: build
+       dh_testdir
+       dh_testroot
+       $(MAKE) DESTDIR=$(CURDIR)/debian/tmp install
+
+binary: build install
+       dh_testdir
+       dh_testroot
+ifeq ($(HOST_ARCH),x86)
+       dh_install --sourcedir=debian/tmp
+else
+       dh_install --sourcedir=debian/tmp -XS06sdbd
+endif
+       dh_strip
+       dh_gencontrol
+       dh_md5sums
+       dh_builddeb
+
+clean:
+       dh_testdir
+       rm -f build-stamp configure-stamp
+       $(MAKE) clean
+       dh_clean
+
diff --git a/debian/sdbd.install b/debian/sdbd.install
new file mode 100644 (file)
index 0000000..5ac7294
--- /dev/null
@@ -0,0 +1,3 @@
+usr/sbin/sdbd
+etc/init.d/sdbd
+etc/rc.d/rc3.d/S06sdbd
index b923b27..8cba86b 100644 (file)
@@ -2,7 +2,8 @@
 - Version up to 3.0.1
 * Thu Oct 31 2013 Junfeng Dong <junfeng.dong@intel.com> submit/tizen/20131011.084016@81e3d5b
 - Fix some runtime issue in 3.0
-
+* 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>
  - supports platform gdbserver
 * Mon Dec 02 2012 Yoonki Park <yoonki.park@samsung.com>
diff --git a/packaging/sdbd.service b/packaging/sdbd.service
new file mode 100644 (file)
index 0000000..76a066e
--- /dev/null
@@ -0,0 +1,8 @@
+[Unit]
+Description=sdbd
+
+[Service]
+Type=forking
+PIDFile=/tmp/.sdbd.pid
+RemainAfterExit=yes
+ExecStart=/usr/sbin/sdbd
index 65da04a..4260794 100644 (file)
@@ -2,7 +2,7 @@
 
 Name:       sdbd
 Summary:    SDB daemon
-Version:    3.0.1
+Version:    3.0.2
 Release:    0
 License:    Apache-2.0
 Summary:    SDB daemon
@@ -16,8 +16,17 @@ Source1004:    sdbd_tcp.service
 BuildRequires: capi-system-info-devel >= 0.2.0
 BuildRequires: cmake >= 2.8.3
 BuildRequires:  pkgconfig(libtzplatform-config)
+#BuildRequires: sec-product-features
 BuildRequires: pkgconfig(libsmack)
+BuildRequires: pkgconfig(capi-system-info)
+BuildRequires: pkgconfig(vconf)
+BuildRequires: pkgconfig(glib-2.0)
+BuildRequires: pkgconfig(dbus-1)
+BuildRequires: pkgconfig(dbus-glib-1)
+Requires(post): libprivilege-control
+Requires: sys-assert
 Requires: dbus
+
 %description
 Description: SDB daemon.
 
@@ -27,26 +36,45 @@ Description: SDB daemon.
 cp %{SOURCE1003} .
 
 %build
-%cmake
-make %{?jobs:-j%jobs}
+%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
-%make_install
+mkdir -p %{buildroot}/usr/share/license
+cp LICENSE %{buildroot}/usr/share/license/%{name}
 
+%make_install
+mkdir -p %{buildroot}%{_libdir}/systemd/system
 mkdir -p %{buildroot}%{_unitdir}
-%if %{with emulator}
-install -m 0644 %SOURCE1002 %{buildroot}%{_unitdir}/sdbd.service
-mkdir -p %{buildroot}/%{_unitdir}/emulator.target.wants
-ln -s %{_unitdir}/sdbd.service %{buildroot}/%{_unitdir}/emulator.target.wants/
+%ifarch %{ix86}
+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/
 %else
 install -m 0644 %SOURCE1001 %{buildroot}%{_unitdir}/sdbd.service
 install -m 0644 %SOURCE1004 %{buildroot}%{_unitdir}/sdbd_tcp.service
+mkdir -p %{buildroot}/%{_libdir}/systemd/system/multi-user.target.wants
+ln -s %{_libdir}/systemd/system/sdbd.service %{buildroot}/%{_libdir}/systemd/system/multi-user.target.wants/
 %endif
 
 mkdir -p %{buildroot}%{_prefix}/sbin
 install -m 755 script/sdk_launch %{buildroot}%{_prefix}/sbin/
 
+mkdir -p %{buildroot}/usr/bin
+install -m 755 script/profile_command %{buildroot}/usr/bin/
 
 %post
 . %{_sysconfdir}/tizen-platform.conf
@@ -67,10 +95,13 @@ fi
 %{_prefix}/sbin/sdk_launch
 %attr(0755, root, root) %{_sysconfdir}/init.d/sdbd
 %{_unitdir}/sdbd.service
-%if %{with emulator}
-%{_unitdir}/emulator.target.wants/sdbd.service
+%ifarch %{ix86}
+%{_libdir}/systemd/system/emulator.target.wants/sdbd.service
 %else
 %{_unitdir}/sdbd_tcp.service
+%{_libdir}/systemd/system/multi-user.target.wants/sdbd.service
 %endif
+/usr/share/license/%{name}
+/usr/bin/profile_command
 
 %changelog
index 48f0e6d..949ca4e 100644 (file)
@@ -1,6 +1,7 @@
 [Unit]
 Description=sdbd
 Requires=tizen-system-env.service
+After=tmp.mount
 
 [Service]
 Type=forking
@@ -8,3 +9,6 @@ EnvironmentFile=-/run/tizen-system-env
 PIDFile=/tmp/.sdbd.pid
 RemainAfterExit=yes
 ExecStart=/usr/sbin/sdbd
+
+[Install]
+WantedBy=multi-user.target
\ No newline at end of file
index 579381a..1a2f298 100644 (file)
@@ -1,6 +1,8 @@
 [Unit]
 Description=sdbd
 Before=sensord.service
+After=tmp.mount dbus.service
+#DefaultDependencies=false
 
 [Service]
 Type=forking
@@ -8,7 +10,9 @@ Environment=DISPLAY=:0
 PIDFile=/tmp/.sdbd.pid
 RemainAfterExit=yes
 SmackProcessLabel=User
-ExecStart=/bin/sh -c "/usr/sbin/sdbd `/usr/bin/awk '{match($0, /sdb_port=([0-9]+)/,port_match); match($0, /vm_name=([^, ]*)/,vm_match); print \"--emulator=\" vm_match[1] \":\" port_match[1] \" --connect-to=10.0.2.2:26099\" \" --sensors=10.0.2.2:\"port_match[1]+3 \" --listen-port=\"port_match[1]+1 }' /proc/cmdline`"
+#ExecStartPre=/bin/bash -c "/bin/echo '10.0.2.15/32 system::debugging_network' >> /smack/netlabel"
+ExecStart=/bin/sh -c "/usr/sbin/sdbd `/usr/bin/awk '{match($0, /sdb_port=([0-9]+)/,port_match); match($0, /vm_name=([^, ]*)/,vm_match); print \"--emulator=\" vm_match[1] \":\" port_match[1] \" --connect-to=10.0.2.2:26099\" \" --sensors=10.0.2.2:\"port_match[1]+3 }' /proc/cmdline`"
 
 [Install]
 WantedBy=emulator.target
+
diff --git a/script/profile_command b/script/profile_command
new file mode 100755 (executable)
index 0000000..cdaef64
--- /dev/null
@@ -0,0 +1,90 @@
+#!/bin/bash
+
+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
+
+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 "getversion                get version"
+       echo "killvalgrind              kill valgrind process"
+}
+
+get_probe_map()
+{
+        /bin/cat /usr/lib/da_api_map
+}
+
+kill_manager()
+{
+       $KILL $MANAGER
+       /bin/rm -f $PORTFILE
+}
+
+run_manager()
+{
+       kill_manager
+       $MANAGER
+}
+
+find_unittest()
+{
+       $FIND `$GETAPPINSTALLPATH | /usr/bin/awk '{if (FNR==1) printf $NF}'` -name *.unittest
+}
+
+process_list()
+{
+       /bin/ps -ewo pid,cmd
+}
+
+get_version()
+{
+       echo $VERSION
+}
+
+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 $# -ne 1 ; then
+       print_usage
+       exit 1
+fi
+
+case "$1" in
+       killmanager)
+               kill_manager
+               ;;
+       runmanager)
+               run_manager
+               ;;
+       findunittest)
+               find_unittest
+               ;;
+       process)
+               process_list
+               ;;
+       getversion)
+               get_version
+               ;;
+       killvalgrind)
+               kill_valgrind
+               ;;
+       getprobemap)
+               get_probe_map
+               ;;
+       *)
+               echo "Unknown option!"
+               print_usage
+               ;;
+esac
index 0c01f1b..941f236 100755 (executable)
@@ -11,13 +11,22 @@ SDK_TOOLS_PATH=${TZ_SDK_TOOLS}
 
 print_usage()
 {
-    echo "usage: $0 -p <pkgid> -e <executable> -m <run|debug|da|oprofile> [-P <port>] [-attach <pid>] -t <gtest,gcov> [<args...>]"
+    echo "usage: $0 [-a <appid>] [-p <pkgid>] [-e <executable>] -m <run|debug|da|oprofile> [-P <port>] [-attach <pid>] -t <gtest,gcov> [<args...>]"
 }
 
 first="true"
 
 until [ -z "$1" ]; do
     case "$1" in
+    -a)
+        if [ -z "$2" ]
+        then
+            print_usage
+            exit 1;
+        fi
+        appid=$2
+        shift 2;
+        ;;
     -p)
         if [ -z "$2" ]
         then
@@ -111,6 +120,13 @@ until [ -z "$1" ]; do
     esac
 done
 
+if [ "" != "$appid" ]
+then
+    launch_app_arg1=$appid
+else
+    launch_app_arg1=$pkgid.$exe
+fi
+
 if [ "$mode" = "debug" ]
 then
     if [ "" != "$attach_id" ]
diff --git a/sdbd.manifest b/sdbd.manifest
new file mode 100644 (file)
index 0000000..1effc20
--- /dev/null
@@ -0,0 +1,44 @@
+<manifest>
+    <define>
+        <domain name="sdbd" policy="shared" />
+        <provide>
+            <label name="sdbd::home" />
+        </provide>
+        <request>
+            <smack request="sys-assert::core" type="rwxat" />
+            <smack request="device::app_logging" type="rwxat" />
+            <smack request="device::sys_logging" type="rwxat" />
+            <smack request="pkgmgr" type="rx" />
+            <smack request="pkgmgr::svc" type="rx" />
+            <smack request="pkgmgr::info" type="r" />
+            <smack request="pkgmgr-server" type="r" />
+            <smack request="pkgmgr-client" type="r" />
+            <smack request="aul" type="rx" />
+            <smack request="wrt::wrt-launcher" type="rx" />
+            <smack request="system::media" type="rwxat" />
+            <smack request="sdbd::home" type="rwxat" />
+            <smack request="dbus" type="rwx" />
+            <smack request="system::use_internet" type="w" />
+            <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" />
+            <smack permit="system::debugging_network" type="w" />
+            <smack permit="aul" type="rx" />
+            <smack permit="wrt::wrt-launcher" type="rw" />
+        </permit>
+    </define>
+    <assign>
+        <filesystem path="/usr/lib/*" label="_" exec_label="none"/>
+    </assign>
+    <request>
+        <domain name="sdbd" />
+    </request>
+</manifest>
index cbc6164..740cd2b 100644 (file)
@@ -802,7 +802,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 ec16a0d..63850f3 100644 (file)
  */
 int split_host_port(const char *optarg, char **host, int *port);
 
+/*!
+ * @define print_nullable(s)
+ * Takes string (<tt>const char *</tt>) and returns it or "(null)" literal
+ * in case \c s is NULL.
+ */
+#define print_nullable(s) \
+    (((s) == NULL) ? "(NULL)" : (s))
+
+
+static void print_sdbd_command(FILE *stream, SdbdCommandlineArgs *sdbd_args) {
+    fprintf(stream, "sdbd_port [%d] \n", sdbd_args->sdbd_port);
+    fprintf(stream, "emulator  [%s:%d] \n", print_nullable(sdbd_args->emulator.host), sdbd_args->emulator.port);
+    fprintf(stream, "sdb       [%s:%d] \n", print_nullable(sdbd_args->sdb.host), sdbd_args->sdb.port);
+    fprintf(stream, "sensors   [%s:%d] \n", print_nullable(sdbd_args->sensors.host), sdbd_args->sensors.port);
+}
+
 int parse_sdbd_commandline(SdbdCommandlineArgs *sdbd_args, int argc, char *argv[]) {
        int split_retval;
 
@@ -69,6 +85,7 @@ int parse_sdbd_commandline(SdbdCommandlineArgs *sdbd_args, int argc, char *argv[
                        if (sdbd_args->sdbd_port < 0) {
                                sdbd_args->sdbd_port = DEFAULT_SDB_LOCAL_TRANSPORT_PORT;
                        }
+                       print_sdbd_command(stdout, sdbd_args);
                        break;
                case ARG_S_SENSORS:
                        split_retval = split_host_port(optarg,
@@ -77,6 +94,7 @@ int parse_sdbd_commandline(SdbdCommandlineArgs *sdbd_args, int argc, char *argv[
                        if (split_retval != SDBD_COMMANDLINE_SUCCESS) {
                                return split_retval;
                        }
+                       print_sdbd_command(stdout, sdbd_args);
                        break;
                case ARG_S_SDB:
                        split_retval = split_host_port(optarg,
@@ -85,11 +103,13 @@ int parse_sdbd_commandline(SdbdCommandlineArgs *sdbd_args, int argc, char *argv[
                        if (split_retval != SDBD_COMMANDLINE_SUCCESS) {
                                return split_retval;
                        }
+                       print_sdbd_command(stdout, sdbd_args);
                        break;
                case ARG_S_SDBD_LISTEN_PORT:
                        if (sscanf(optarg, "%d", &sdbd_args->sdbd_port) < 1) {
                                return SDBD_COMMANDLINE_FAILURE;
                        }
+                       print_sdbd_command(stdout, sdbd_args);
                        break;
                case ARG_S_HELP:
                    return SDBD_COMMANDLINE_HELP;
@@ -104,11 +124,15 @@ int parse_sdbd_commandline(SdbdCommandlineArgs *sdbd_args, int argc, char *argv[
                }
        }
 
+       print_sdbd_command(stdout, sdbd_args);
+
        return SDBD_COMMANDLINE_SUCCESS;
 }
 
 
 void apply_sdbd_commandline_defaults(SdbdCommandlineArgs *sdbd_args) {
+       sdbd_args->emulator.port = -1;
+
        sdbd_args->sensors.host = strdup(QEMU_FORWARD_IP);
        sdbd_args->sensors.port = DEFAULT_SENSORS_LOCAL_TRANSPORT_PORT;
 
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 55785ce..2efe0ea 100644 (file)
@@ -34,6 +34,7 @@
 #include "sdb.h"
 #include "file_sync_service.h"
 #include "sdktools.h"
+#include "sdbd_plugin.h"
 
 #define SYNC_TIMEOUT 15
 
@@ -92,6 +93,13 @@ static void set_syncfile_smack_label(char *src) {
                 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));
                 }
+
+                /* Todo: The following code is from tizen 2.4
+                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);
             }
         } else{
@@ -102,6 +110,13 @@ static void set_syncfile_smack_label(char *src) {
         if (smack_setlabel(src, SMACK_SYNC_FILE_LABEL, SMACK_LABEL_ACCESS) == -1) {
             D("unable to set sync file smack label %s due to %s\n", SMACK_SYNC_FILE_LABEL, strerror(errno));
         }
+
+        /* Todo: The following code is from tizen 2.4
+        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);
+        }
+        */
     }
 }
 
@@ -117,12 +132,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:%s\n", strerror(errno));
+            D("sync notify read errno:%d\n", errno);
             exit(-1);
         }
 
@@ -130,6 +145,7 @@ static void sync_read_label_notify(int s)
             D("sync notify child process exit\n");
             exit(-1);
         }
+        buffer[len] = '\0';
         char *path = buffer;
         path++;
         path++;
@@ -158,7 +174,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\") -> %s\n", name, strerror(errno));
+            D("mkdir(\"%s\") -> errno:%d\n", name, errno);
             *x = '/';
             return ret;
         }
@@ -179,7 +195,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: %s\n", path, strerror(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);
@@ -200,6 +216,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] = '/';
@@ -209,11 +228,11 @@ static int do_list(int s, const char *path)
 
     d = opendir(path);
     if(d == NULL) {
-        D("failed to open dir due to: %s\n", strerror(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
@@ -222,7 +241,7 @@ static int do_list(int s, const char *path)
             continue;
         }
 
-        strcpy(fname, de->d_name);
+        s_strncpy(fname, de->d_name, sizeof tmp);
         if(lstat(tmp, &st) == 0) {
             msg.dent.mode = htoll(st.st_mode);
             msg.dent.size = htoll(st.st_size);
@@ -267,7 +286,44 @@ static int fail_message(int s, const char *reason)
 
 static int fail_errno(int s)
 {
-    return fail_message(s, strerror(errno));
+       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 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) {
+    if (access(CMD_MEDIADB_UPDATE, F_OK) != 0) {
+        D("%s: command not found\n", CMD_MEDIADB_UPDATE);
+        return;
+    }
+
+    if (strstr(path, VAR_ABS_PATH) == path) {
+        path += 4;
+    }
+
+    if (strstr(path, MEDIA_CONTENTS_PATH1) != NULL) {
+        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) {
+        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);
+        D("media db update done to %s\n", MEDIA_CONTENTS_PATH3);
+    }
+    return;
 }
 
 static int handle_send_file(int s, int noti_fd, char *path, mode_t mode, char *buffer)
@@ -344,6 +400,7 @@ static int handle_send_file(int s, int noti_fd, char *path, mode_t mode, char *b
         return -1;
     }
     sync_send_label_notify(noti_fd, path, 1);
+    sync_mediadb(path);
     return 0;
 
 fail:
@@ -403,12 +460,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;
@@ -427,6 +502,10 @@ 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_pkg_file_path(path)) {
+        mode = 0644;
+        is_link = 0;
+    }
 
     // sdb does not allow to check that file exists or not. After deleting old file and creating new file again unconditionally.
     sdb_unlink(path);
@@ -457,6 +536,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;
index 61b462a..94a52b6 100644 (file)
@@ -76,6 +76,7 @@ typedef union {
 } syncmsg;
 
 void init_sdk_sync_permit_rule_regx(void);
+
 void file_sync_service(int fd, void *cookie);
 void file_sync_subproc(int fd, void *cookie);
 int do_sync_ls(const char *path);
index 7594100..42e5785 100644 (file)
@@ -240,8 +240,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 8b9f7cc..2fff648 100644 (file)
--- a/src/sdb.c
+++ b/src/sdb.c
@@ -1,5 +1,4 @@
-/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*-
- *
+/*
  * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
  *
  * Licensed under the Apache License, Version 2.0 (the License);
@@ -29,6 +28,8 @@
 #include <grp.h>
 #include <netdb.h>
 #include <tzplatform_config.h>
+#include <pthread.h>
+#include <dlfcn.h>
 
 #include "sysdeps.h"
 #include "sdb.h"
@@ -36,6 +37,8 @@
 #if !SDB_HOST
 #include "commandline_sdbd.h"
 #endif
+#include "utils.h"
+#include "sdktools.h"
 
 #if !SDB_HOST
 #include <linux/prctl.h>
 #include "usb_vendors.h"
 #endif
 #include <system_info.h>
+#include <vconf.h>
+#include "utils.h"
 #define PROC_CMDLINE_PATH "/proc/cmdline"
-#define SYSTEM_INFO_KEY_MODEL           "http://tizen.org/system/model_name"
+#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
@@ -72,18 +85,33 @@ int is_emulator(void) {
 #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;
+    }
+}
+
+void* g_sdbd_plugin_handle = NULL;
+SDBD_PLUGIN_CMD_PROC_PTR sdbd_plugin_cmd_proc = NULL;
+
 void handle_sig_term(int sig) {
 #ifdef SDB_PIDPATH
     if (access(SDB_PIDPATH, F_OK) == 0)
         sdb_unlink(SDB_PIDPATH);
 #endif
-    //kill(getpgid(getpid()),SIGTERM);
-    //killpg(getpgid(getpid()),SIGTERM);
-    if (!is_emulator()) {
-        exit(0);
-    } else {
-       // do nothing on a emulator
-    }
+    char *cmd1_args[] = {"/usr/bin/killall", "/usr/bin/debug_launchpad_preloading_preinitializing_daemon", NULL};
+    spawn("/usr/bin/killall", cmd1_args);
+    sdb_sleep_ms(1000);
 }
 
 static const char *sdb_device_banner = "device";
@@ -103,7 +131,7 @@ void fatal_errno(const char *fmt, ...)
 {
     va_list ap;
     va_start(ap, fmt);
-    fprintf(stderr, "error: %s: ", strerror(errno));
+    fprintf(stderr, "errno: %d: ", errno);
     vfprintf(stderr, fmt, ap);
     fprintf(stderr, "\n");
     va_end(ap);
@@ -319,7 +347,7 @@ static void send_close(unsigned local, unsigned remote, atransport *t)
     p->msg.arg1 = remote;
     send_packet(p, t);
 }
-static int device_status = 0; // 0:online, 1: password locked later
+
 static void send_connect(atransport *t)
 {
     D("Calling send_connect \n");
@@ -330,6 +358,11 @@ static void send_connect(atransport *t)
 
     char device_name[256]={0,};
     int r = 0;
+    int status = 0;
+    if (is_pwlocked()) {
+        status = 1;
+        t->connection_state = CS_PWLOCK;
+    }
 
     if (is_emulator()) {
         r = get_emulator_name(device_name, sizeof device_name);
@@ -337,9 +370,9 @@ static void send_connect(atransport *t)
         r = get_device_name(device_name, sizeof device_name);
     }
     if (r < 0) {
-        snprintf((char*) cp->data, sizeof cp->data, "%s::%s::%d", sdb_device_banner, DEFAULT_DEVICENAME, device_status);
+        snprintf((char*) cp->data, sizeof cp->data, "%s::%s::%d", sdb_device_banner, DEFAULT_DEVICENAME, status);
     } else {
-        snprintf((char*) cp->data, sizeof cp->data, "%s::%s::%d", sdb_device_banner, device_name, device_status);
+        snprintf((char*) cp->data, sizeof cp->data, "%s::%s::%d", sdb_device_banner, device_name, status);
     }
 
     D("CNXN data:%s\n", (char*)cp->data);
@@ -353,6 +386,21 @@ static void send_connect(atransport *t)
 #endif
 }
 
+static void send_device_status()
+{
+    D("broadcast device status\n");
+    apacket* cp = get_apacket();
+    cp->msg.command = A_STAT;
+    cp->msg.arg0 = is_pwlocked();
+    cp->msg.arg1 = 0;
+
+    broadcast_transport(cp);
+
+    //all broadcasted packets are memory copied
+    //so, we should call put_apacket
+    put_apacket(cp);
+}
+
 static char *connection_state_name(atransport *t)
 {
     if (t == NULL) {
@@ -388,7 +436,8 @@ static int get_str_cmdline(char *src, char *dest, char str[], int str_size) {
         return -1;
     }
 
-    s_strncpy(str, s + strlen(dest), len);
+    strncpy(str, s + strlen(dest), len);
+    str[len]='\0';
     return len;
 }
 
@@ -415,7 +464,7 @@ int get_emulator_name(char str[], int str_size) {
 
 int get_device_name(char str[], int str_size) {
     char *value = NULL;
-    int r = system_info_get_platform_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;
@@ -444,6 +493,60 @@ int get_device_name(char str[], int str_size) {
     return -1;
 }
 
+static int get_cmdline_value(char *split, char str[], int str_size) {
+    char cmdline[512];
+    int fd = unix_open(PROC_CMDLINE_PATH, O_RDONLY);
+
+    if (fd < 0) {
+        D("fail to read /proc/cmdline\n");
+        return -1;
+    }
+    if(read_line(fd, cmdline, sizeof(cmdline))) {
+        D("qemu cmd: %s\n", cmdline);
+        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;
+        }
+    }
+    sdb_close(fd);
+    return 0;
+}
+
+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;
@@ -535,17 +638,22 @@ void handle_packet(apacket *p, atransport *t)
         break;
 
     case A_OPEN: /* OPEN(local-id, 0, "destination") */
-        if(t->connection_state != CS_OFFLINE) {
-            char *name = (char*) p->data;
-            name[p->msg.data_length > 0 ? p->msg.data_length - 1 : 0] = 0;
-            s = create_local_service_socket(name);
-            if(s == 0) {
-                send_close(0, p->msg.arg0, t);
-            } else {
-                s->peer = create_remote_socket(p->msg.arg0, t);
-                s->peer->peer = s;
-                send_ready(s->id, s->peer->id, t);
-                s->ready(s);
+        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(t->connection_state != CS_OFFLINE) {
+                char *name = (char*) p->data;
+                name[p->msg.data_length > 0 ? p->msg.data_length - 1 : 0] = 0;
+                s = create_local_service_socket(name);
+                if(s == 0) {
+                    send_close(0, p->msg.arg0, t);
+                } else {
+                    s->peer = create_remote_socket(p->msg.arg0, t);
+                    s->peer->peer = s;
+                    send_ready(s->id, s->peer->id, t);
+                    s->ready(s);
+                }
             }
         }
         break;
@@ -811,6 +919,10 @@ static void sdb_cleanup(void)
 //    if(required_pid > 0) {
 //        kill(required_pid, SIGKILL);
 //    }
+    if (g_sdbd_plugin_handle) {
+        dlclose(g_sdbd_plugin_handle);
+        g_sdbd_plugin_handle = NULL;
+    }
 }
 
 void start_logging(void)
@@ -1096,6 +1208,40 @@ static void init_drop_privileges() {
 #endif
 }
 
+int is_pwlocked(void) {
+    int pwlock_status = 0;
+    int pwlock_type = 0;
+
+    if (vconf_get_int(VCONFKEY_IDLE_LOCK_STATE, &pwlock_status)) {
+        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_NONE) && (pwlock_type != SETTING_SCREEN_LOCK_TYPE_SWIPE))) {
+        D("device has been locked\n");
+        return 1; // locked!
+    }
+#endif
+    return 0; // unlocked!
+}
+
 int should_drop_privileges() {
     if (rootshell_mode == 1) { // if root, then don't drop
         return 0;
@@ -1103,20 +1249,139 @@ int should_drop_privileges() {
     return 1;
 }
 
+static void *pwlock_tmp_cb(void *x)
+{
+    int status = is_pwlocked();
+    /**
+     * FIXME: make it callback using vconf_notify_key_changed
+     */
+
+    while(1) {
+        if (status != is_pwlocked()) {
+            send_device_status();
+            status = is_pwlocked();
+        }
+        sdb_sleep_ms(3000);
+    }
+    return 0;
+}
+
+void register_pwlock_cb() {
+    D("registerd vconf callback\n");
+
+    sdb_thread_t t;
+    if(sdb_thread_create( &t, pwlock_tmp_cb, NULL)){
+        D("cannot create service thread\n");
+        return;
+    }
+}
+
+#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[] = { GID_DEVELOPER, SID_APP_LOGGING, SID_SYS_LOGGING, SID_INPUT };
+    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(GID_DEVELOPER) != 0) {
-        D("set group id failed (errno: %d, %s)\n", errno, strerror(errno));
+    if (setgid(SID_DEVELOPER) != 0) {
+        D("set group id failed (errno: %d)\n", errno);
         return -1;
     }
 
     if (setuid(SID_DEVELOPER) != 0) {
-        D("set user id failed (errno: %d, %s)\n", errno, strerror(errno));
+        D("set user id failed (errno: %d)\n", errno);
         return -1;
     }
 
@@ -1139,6 +1404,226 @@ int set_developer_privileges() {
 }
 #define ONDEMAND_ROOT_PATH tzplatform_getenv(TZ_SDK_HOME)
 
+static void execute_required_process() {
+    char *cmd_args[] = {"/usr/bin/debug_launchpad_preloading_preinitializing_daemon",NULL};
+
+    spawn("/usr/bin/debug_launchpad_preloading_preinitializing_daemon", cmd_args);
+}
+
+/* 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_ENABLED);
+        }
+        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;
+    }
+
+    D("shell command : %s\n", in_buf);
+
+    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;
+    }
+
+    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;
 
@@ -1163,49 +1648,241 @@ static void init_sdk_requirements() {
         }
     }
 
+    execute_required_process();
+
+    register_pwlock_cb();
+
+    if (is_emulator()) {
+        register_bootdone_cb();
+    }
 }
 #endif /* !SDB_HOST */
 
-static void get_plugin_capability(void)
+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 len;
-       char *usb_state;
-       char *sock_state;
+    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);
+    }
 
-       if (is_emulator())
-               usb_state = SDBD_CAP_RET_DISABLED;
-       else
-               usb_state = SDBD_CAP_RET_ENABLED;
 
-       sock_state = SDBD_CAP_RET_ENABLED;
+    // 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);
+        }
+    }
 
-       len = sizeof(g_capabilities.usbproto_support);
-       snprintf(g_capabilities.usbproto_support, len,
-                       "%s", usb_state);
 
-       len = sizeof(g_capabilities.sockproto_support);
-       snprintf(g_capabilities.sockproto_support, len,
-                       "%s", sock_state);
+    // 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);
+    }
 }
 
 static int is_support_usbproto()
 {
-       return (!strncmp(g_capabilities.usbproto_support,
-                               SDBD_CAP_RET_ENABLED, strlen(SDBD_CAP_RET_ENABLED)));
+    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)));
+    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
-    get_plugin_capability();
+    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
 
@@ -1276,37 +1953,38 @@ int sdb_main(int is_daemon, int server_port)
         }
     }
 
-       if (is_support_usbproto()) {
-           if (!is_emulator()) {
-               /* choose the usb gadget backend */
-               if (access(USB_NODE_FILE, F_OK) == 0) {
-                   /* legacy kernel-based sdb gadget */
-                   usb_init =    &linux_usb_init;
-                   usb_cleanup = &linux_usb_cleanup;
-                   usb_write =   &linux_usb_write;
-                   usb_read =    &linux_usb_read;
-                   usb_close =   &linux_usb_close;
-                   usb_kick =    &linux_usb_kick;
-               } else {
-                   /* functionfs based gadget */
-                   usb_init =    &ffs_usb_init;
-                   usb_cleanup = &ffs_usb_cleanup;
-                   usb_write =   &ffs_usb_write;
-                   usb_read =    &ffs_usb_read;
-                   usb_close =   &ffs_usb_close;
-                   usb_kick =    &ffs_usb_kick;
-               }
-               // listen on USB
-               usb_init();
-           }
-       }
+    if (is_support_usbproto()) {
+        /* choose the usb gadget backend */
+        if (access(USB_NODE_FILE, F_OK) == 0) {
+            /* legacy kernel-based sdb gadget */
+            usb_init =    &linux_usb_init;
+            usb_cleanup = &linux_usb_cleanup;
+            usb_write =   &linux_usb_write;
+            usb_read =    &linux_usb_read;
+            usb_close =   &linux_usb_close;
+            usb_kick =    &linux_usb_kick;
+        } else {
+            /* functionfs based gadget */
+            usb_init =    &ffs_usb_init;
+            usb_cleanup = &ffs_usb_cleanup;
+            usb_write =   &ffs_usb_write;
+            usb_read =    &ffs_usb_read;
+            usb_close =   &ffs_usb_close;
+            usb_kick =    &ffs_usb_kick;
+        }
 
-       if (is_support_sockproto()) {
-               /* by default don't listen on local transport but
-                * listen if suitable command line argument has been provided */
-               if (sdbd_commandline_args.sdbd_port >= 0)
-                       local_init(sdbd_commandline_args.sdbd_port);
-       }
+        // listen on USB
+        usb_init();
+    }
+    if (is_support_sockproto()) {
+        /* by default don't listen on local transport but
+         * listen if suitable command line argument has been provided */
+        if (sdbd_commandline_args.sdbd_port >= 0) {
+            local_init(sdbd_commandline_args.sdbd_port);
+        } else {
+            local_init(DEFAULT_SDB_LOCAL_TRANSPORT_PORT);
+        }
+    }
 
 #if 0 /* tizen specific */
     D("sdb_main(): pre init_jdwp()\n");
@@ -1344,7 +2022,7 @@ void connect_device(char* host, char* buffer, int buffer_size)
     char hostbuf[100];
     char serial[100];
 
-    strncpy(hostbuf, host, sizeof(hostbuf) - 1);
+    s_strncpy(hostbuf, host, sizeof(hostbuf) - 1);
     if (portstr) {
         if (portstr - host >= sizeof(hostbuf)) {
             snprintf(buffer, buffer_size, "bad host name %s", host);
@@ -1435,6 +2113,31 @@ void connect_emulator(char* port_spec, char* buffer, int buffer_size)
 }
 #endif
 
+int copy_packet(apacket* dest, apacket* src) {
+
+    if(dest == NULL) {
+        D("dest packet is NULL\n");
+        return -1;
+    }
+
+    if(src == NULL) {
+        D("src packet is NULL\n");
+        return -1;
+    }
+
+    dest->next = src->next;
+    dest->ptr = src->ptr;
+    dest->len = src->len;
+
+    int data_length = src->msg.data_length;
+    if(data_length > MAX_PAYLOAD) {
+        data_length = MAX_PAYLOAD;
+    }
+    memcpy(&(dest->msg), &(src->msg), sizeof(amessage) + data_length);
+
+    return 0;
+}
+
 int handle_host_request(char *service, transport_type ttype, char* serial, int reply_fd, asocket *s)
 {
     atransport *transport = NULL;
@@ -1671,7 +2374,7 @@ int main(int argc, char **argv)
 
 #if !SDB_HOST
     if (daemonize() < 0)
-        fatal("daemonize() failed: %.200s", strerror(errno));
+        fatal("daemonize() failed: errno:%d", errno);
 #endif
 
     start_device_log();
index da25ab1..9cef525 100644 (file)
--- a/src/sdb.h
+++ b/src/sdb.h
 
 #include <limits.h>
 #include <stdlib.h>
+#include <stddef.h>
 
 #include "transport.h"  /* readx(), writex() */
 #include "fdevent.h"
+#include "sdbd_plugin.h"
 #if !SDB_HOST
 #include "commandline_sdbd.h"
 #endif
 #define A_OKAY 0x59414b4f
 #define A_CLSE 0x45534c43
 #define A_WRTE 0x45545257
+#define A_STAT 0x54415453
 
-#define A_VERSION 0x01000000        // SDB protocol version
+#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
 
@@ -92,11 +96,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
         */
 
@@ -228,16 +227,54 @@ struct alistener
     adisconnect  disconnect;
 };
 
-#define SDBD_CAP_RET_ENABLED  "enabled"
-#define SDBD_CAP_RET_DISABLED "disabled"
+#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 usbproto_support[CAPBUF_ITEMSIZE];     // enabled or disabled
-       char sockproto_support[CAPBUF_ITEMSIZE];    // enabled or disabled
+    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);
 
 asocket *find_local_socket(unsigned id);
@@ -271,6 +308,7 @@ int sdb_main(int is_daemon, int server_port);
 void init_transport_registration(void);
 int  list_transports(char *buf, size_t  bufsize);
 void update_transports(void);
+void broadcast_transport(apacket *p);
 
 asocket*  create_device_tracker(void);
 
@@ -335,7 +373,8 @@ 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 rootshell_mode; // 0: developer, 1: root
+int booting_done; // 0: platform booting is in progess 1: platform booting is done
 
 // This is the users and groups config for the platform
 
@@ -350,6 +389,7 @@ int rootshell_mode;// 0: developer, 1: root
 
 #endif
 
+int is_pwlocked(void);
 int should_drop_privileges(void);
 int set_developer_privileges();
 void set_root_privileges();
@@ -357,6 +397,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);
@@ -500,7 +543,7 @@ void ffs_usb_kick(usb_handle *h);
 void linux_usb_init();
 void linux_usb_cleanup();
 int linux_usb_write(usb_handle *h, const void *data, int len);
-int linux_usb_read(usb_handle *h, void *data, int len);
+int linux_usb_read(usb_handle *h, void *data, unsigned len);
 int linux_usb_close(usb_handle *h);
 void linux_usb_kick(usb_handle *h);
 
@@ -524,6 +567,7 @@ int connection_state(atransport *t);
 #define CS_RECOVERY   4
 #define CS_NOPERM     5 /* Insufficient permissions to communicate with the device */
 #define CS_SIDELOAD   6
+#define CS_PWLOCK     10
 
 extern int HOST;
 extern int SHELL_EXIT_NOTIFY_FD;
@@ -535,6 +579,7 @@ extern SdbdCommandlineArgs sdbd_commandline_args;
 
 int sendfailmsg(int fd, const char *reason);
 int handle_host_request(char *service, transport_type ttype, char* serial, int reply_fd, asocket *s);
+int copy_packet(apacket* dest, apacket* src);
 
 int is_emulator(void);
 #define DEFAULT_DEVICENAME "unknown"
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 d1cd388..814e066 100644 (file)
 #include "sdktools.h"
 #include "strutils.h"
 #include "fileutils.h"
+#include "utils.h"
 
 struct sudo_command root_commands[] = {
-    /* 0 */ {"killall", "/usr/bin/killall"},
-    /* 1 */ {"zypper", "/usr/bin/zypper"},
-    /* 2 */ {"da_command", "/usr/bin/da_command"},
-    /* 3 */ {"oprofile", "/usr/bin/oprofile_command"},
-    /* end */ {NULL, NULL}
+    /* 0 */
+    { "profile", "/usr/bin/profile_command",
+        { "killmanager",
+        "runmanager",
+        "findunittest",
+        "process",
+        "getversion",
+        "killvalgrind",
+        "getprobemap",
+        NULL
+        }
+    },
+    /* end */
+    { NULL, NULL, NULL }
 };
 
-struct arg_permit_rule sdk_arg_permit_rule[] = {
-    /* 2 */ {"gcove_env1", "^GCOV_PREFIX=((/opt/apps)|(/opt/usr/apps))/[a-zA-Z0-9]{10}/data$", 1},
-    /* 2 */ {"gcove_env2", "GCOV_PREFIX_STRIP=0", 0},
-    /* 2 */ {"gcove_env3", "LD_LIBRARY_PATH=/home/developer/sdk_tools/gtest/usr/lib:$LD_LIBRARY_PATH", 0},
-    /* 2 */ {"gcove_env4", "TIZEN_LAUNCH_MODE=debug", 0},
-    /* 2 */ {"da_env1", "LD_PRELOAD=/usr/lib/da_probe_osp.so", 0},
-    /* 2 */ {"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}
+static struct command_suffix
+{
+    const char *name; // comments for human
+    const char *suffix; //pattern
 };
 
-void init_sdk_arg_permit_rule_pattern(void)
-{
-    asprintf(&sdk_arg_permit_rule[0].pattern, "^GCOV_PREFIX=((%s)|(%s))/[a-zA-Z0-9]{10}/data$", APP_INSTALL_PATH_PREFIX1, APP_INSTALL_PATH_PREFIX2);
-    asprintf(&sdk_arg_permit_rule[1].pattern, "GCOV_PREFIX_STRIP=0");
-    asprintf(&sdk_arg_permit_rule[2].pattern, "LD_LIBRARY_PATH=%s/gtest/usr/lib:$LD_LIBRARY_PATH", DEV_INSTALL_PATH_PREFIX, APP_INSTALL_PATH_PREFIX2);
-    asprintf(&sdk_arg_permit_rule[3].pattern, "TIZEN_LAUNCH_MODE=debug");
-    asprintf(&sdk_arg_permit_rule[4].pattern, "LD_PRELOAD=/usr/lib/da_probe_osp.so", DEV_INSTALL_PATH_PREFIX, APP_INSTALL_PATH_PREFIX2);
-    asprintf(&sdk_arg_permit_rule[5].pattern, "^\\-\\-gtest_output=xml:((%s)|(%s))/[a-zA-Z0-9]{10}/data/[a-zA-Z0-9_\\-]{1,30}\\.xml$", APP_INSTALL_PATH_PREFIX1, APP_INSTALL_PATH_PREFIX2);
-}
+static struct command_suffix CMD_SUFFIX_DENY_KEYWORD[] = {
+        /* 0 */   {"pipe", "|"},
+        /* 1 */   {"redirect", ">"},
+        /* 2 */   {"semicolon", ";"}, // separated list is executed
+        /* 3 */   {"and", "&"},
+        /* 4 */   {"command_substitution1", "$"},
+        /* 5 */   {"command_substitution2", "`"},
+        /* end */ {NULL, NULL}
+};
 
+/**
+ * return 1 if the arg is arrowed, otherwise 0 is denied
+ */
+static int is_cmd_suffix_denied(const char* arg) {
+    int i;
 
-int verify_commands(const char *arg1) {
-    if (arg1 != NULL) {
-        if (verify_root_commands(arg1)) {
-            // do not drop privilege only if root auth is required
+    for (i=0; CMD_SUFFIX_DENY_KEYWORD[i].name != NULL; i++) {
+        if (strstr(arg, CMD_SUFFIX_DENY_KEYWORD[i].suffix) != NULL) {
+            D("cmd suffix denied:%s\n", arg);
             return 1;
         }
     }
-    // doing these steps if we don't have root permission
-    if (should_drop_privileges()) {
-        set_developer_privileges();
+    D("cmd suffix arrowed:%s\n", arg);
+    return 0;
+}
+
+static int get_application_install_path(char* pkg_path) {
+    FILE *fp = NULL;
+    char ret_str[PATH_MAX+64] = {0,};
+    int len = 0;
+
+    fp = popen("/usr/bin/pkgcmd -a", "r");
+    if (fp == NULL) {
+        D("failed : popen pkgcmd -a\n");
+        return 0;
     }
+    if (!fgets(ret_str, PATH_MAX+64, fp)) {
+        D("failed : fgets pkgcmd -a\n");
+        pclose(fp);
+        return 0;
+    }
+    pclose(fp);
+
+    len = strlen(ret_str);
+    while(ret_str[--len]=='\n');
+    ret_str[len + 1] = '\0';
+
+    if (sscanf(ret_str, "Tizen Application Installation Path: %s", pkg_path) != 1) {
+        D("failed : parsing fail (str:%s)\n", ret_str);
+        return 0;
+    }
+
+    D("Tizen install path: %s\n", pkg_path);
+    return 1;
+}
+
+int is_pkg_file_path(const char* path) {
+    regex_t regex;
+    int ret;
+    char pkg_path[PATH_MAX] = {0,};
+    char pkg_path_regx[PATH_MAX+64] = {0,};
+
+    if (!get_application_install_path(pkg_path)) {
+        D("failed to get application install path\n");
+        return 0;
+    }
+
+    snprintf(pkg_path_regx, sizeof(pkg_path_regx),
+        "^.*(%s/tmp/)+[a-zA-Z0-9_\\-\\.]*\\.(wgt|tpk),*[0-9]*$", pkg_path);
+
+    ret = regcomp(&regex, pkg_path_regx, REG_EXTENDED);
+    if (ret){
+        D("failed : recomp (error:%d)\n", ret);
+        return 0;
+    }
+
+    ret = regexec(&regex, path, 0, NULL, 0);
+    regfree(&regex);
+
+    if (ret){
+        D("This path is NOT package file: %s\n", path);
+        return 0;
+    }
+
+    D("This path is temporary package file: %s\n", path);
     return 1;
 }
 
@@ -81,54 +150,27 @@ 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) {
+    // in case of profile_command
     case 0: {
-        if (cnt == 2) {
-            if (verify_app_path(tokens[1])) {
-                ret = 1;
-            }
-        }
-        break;
-    }
-    case 1: {
-        ret = 1;
-        break;
-    }
-    case 2: {
-        ret = 1;
-        break;
-    }
-    case 3: {
-        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);
+        ret = 0;
+        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");
+            if (ret == 0) {
+                D("not found permitted arguments :%s\n", tokens[1]);
+            }
         }
-
-        ret = 1;
         break;
     }
     default: {
@@ -145,15 +187,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;
@@ -178,326 +211,6 @@ int regcmp(const char* pattern, const char* str) {
     return 0;
 }
 
-int env_verify(const char* arg) {
-    int i;
-    init_sdk_arg_permit_rule_pattern();
-    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);
-    for (i = 0; i <= 6; i++){
-       free(sdk_arg_permit_rule[i].pattern);
-    }
-    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 debug = 0;
-            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 %s\n", SMACK_LEBEL_SUBJECT_PATH, strerror(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] = {0, };
-    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) {
-        strncpy(appid, buffer, sizeof(appid) - 1);
-        free(buffer);
-    } else {
-        strncpy(appid, "_", sizeof(appid) - 1);
-    }
-    new_appid = (char *)malloc(sizeof(appid)+1);
-    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 %s\n", SMACK_LEBEL_SUBJECT_PATH, strerror(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 de805af..59d8d98 100644 (file)
@@ -6,11 +6,12 @@ extern "C" {
 #endif
 #include <tzplatform_config.h>
 
+#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*/
 };
@@ -37,18 +38,11 @@ struct arg_permit_rule
 #define SDBD_LABEL_NAME                         "sdbd"
 #define SDK_HOME_LABEL_NAME                     "sdbd::home"
 
-void init_sdk_arg_permit_rule_pattern(void);
-int verify_commands(const char *arg1);
 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 2b2174e..e845e4f 100644 (file)
 #include <system_info.h>
 #include <tzplatform_config.h>
 
-#define SYSTEM_INFO_KEY_MODEL           "http://tizen.org/system/model_name"
-#define SYSTEM_INFO_KEY_PLATFORM_NAME   "http://tizen.org/system/platform.name"
+#include <vconf.h>
+#include <limits.h>
+
+#include <termios.h>
+#include <sys/ioctl.h>
 
 typedef struct stinfo stinfo;
 
@@ -84,6 +87,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;
 
@@ -164,23 +172,35 @@ void restart_tcp_service(int fd, void *cookie)
     sdb_close(fd);
 }
 
+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")) {
@@ -190,10 +210,11 @@ void rootshell_service(int fd, void *cookie)
             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");
+    free(mode);
     sdb_close(fd);
 }
 
@@ -231,7 +252,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);
@@ -268,14 +289,14 @@ void inoti_service(int fd, void *arg)
             D( "inoti read failed\n");
             goto done;
         }
-
-        while ( i < length ) {
-            struct inotify_event *event = ( struct inotify_event * )&buffer[i];
+        while (i >= 0 && i <= (length - EVENT_SIZE)) {
+            struct inotify_event *event = (struct inotify_event *) &buffer[i];
             if (event->len) {
-                if ( event->mask & IN_CREATE) {
+                if (event->mask & IN_CREATE) {
                     if (!(event->mask & IN_ISDIR)) {
                         char *cspath = NULL;
-                        int len = asprintf(&cspath, "%s/%s", CS_PATH, event->name);
+                        int len = asprintf(&cspath, "%s/%s", CS_PATH,
+                                event->name);
                         D( "The file %s was created.\n", cspath);
                         writex(fd, cspath, len);
                         if (cspath != NULL) {
@@ -284,6 +305,9 @@ void inoti_service(int fd, void *arg)
                     }
                 }
             }
+            if (i + EVENT_SIZE + event->len < event->len) { // in case of integer overflow
+                break;
+            }
             i += EVENT_SIZE + event->len;
         }
     }
@@ -362,35 +386,41 @@ static int create_service_thread(void (*func)(int, void *), void *cookie)
 
 #if !SDB_HOST
 
-static int create_subprocess(const char *cmd, const char *arg0, const char *arg1, pid_t *pid)
+static void redirect_and_exec(int pts, const char *cmd, const char *argv[], const char *envp[])
 {
-#ifdef HAVE_WIN32_PROC
-    D("create_subprocess(cmd=%s, arg0=%s, arg1=%s)\n", cmd, arg0, arg1);
-    fprintf(stderr, "error: create_subprocess not implemented on Win32 (%s %s %s)\n", cmd, arg0, arg1);
-    return -1;
-#else /* !HAVE_WIN32_PROC */
-    char *devname;
+    dup2(pts, 0);
+    dup2(pts, 1);
+    dup2(pts, 2);
+
+    sdb_close(pts);
+
+    execve(cmd, argv, envp);
+}
+
+static int create_subprocess(const char *cmd, pid_t *pid, const char *argv[], const char *envp[])
+{
+    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;
     }
@@ -406,32 +436,34 @@ static int create_subprocess(const char *cmd, const char *arg0, const char *arg1
             exit(-1);
         }
 
-        dup2(pts, 0);
-        dup2(pts, 1);
-        dup2(pts, 2);
-
-        sdb_close(pts);
         sdb_close(ptm);
 
         // set OOM adjustment to zero
         {
             char text[64];
-            snprintf(text, sizeof text, "/proc/%d/oom_score_adj", getpid());
+            //snprintf(text, sizeof text, "/proc/%d/oom_score_adj", getpid());
+            snprintf(text, sizeof text, "/proc/%d/oom_adj", getpid());
             int fd = sdb_open(text, O_WRONLY);
             if (fd >= 0) {
                 sdb_write(fd, "0", 1);
                 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);
             }
         }
 
-        verify_commands(arg1);
-
-        execl(cmd, cmd, arg0, arg1, NULL);
-        fprintf(stderr, "- exec '%s' failed: %s (%d) -\n",
-                cmd, strerror(errno), errno);
+        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);
     } else {
         // Don't set child's OOM adjustment to zero.
@@ -440,15 +472,14 @@ static int create_subprocess(const char *cmd, const char *arg0, const char *arg1
         // """sdb: unable to open /proc/644/oom_adj""" seen in some logs.
         return ptm;
     }
-#endif /* !HAVE_WIN32_PROC */
 }
 #endif  /* !SDB_HOST */
 
-#if SDB_HOST
 #define SHELL_COMMAND "/bin/sh"
-#else
-#define SHELL_COMMAND "/bin/sh" /* tizen specific */
-#endif
+#define LOGIN_COMMAND "/bin/login"
+#define SDK_USER      "developer"
+#define SUPER_USER    "root"
+#define LOGIN_CONFIG  "/etc/login.defs"
 
 #if !SDB_HOST
 static void subproc_waiter_service(int fd, void *cookie)
@@ -461,7 +492,6 @@ static void subproc_waiter_service(int fd, void *cookie)
         pid_t p = waitpid(pid, &status, 0);
         if (p == pid) {
             D("fd=%d, post waitpid(pid=%d) status=%04x\n", fd, p, status);
-            
             if (WIFEXITED(status)) {
                 D("*** Exit code %d\n", WEXITSTATUS(status));
                 break;
@@ -483,17 +513,160 @@ static void subproc_waiter_service(int fd, void *cookie)
     }
 }
 
-static int create_subproc_thread(const char *name)
+static void get_env(char *key, char **env)
+{
+    FILE *fp;
+    char buf[1024];
+    int i;
+    char *s, *e, *value;
+
+    fp = fopen (LOGIN_CONFIG, "r");
+    if (NULL == fp) {
+        return;
+    }
+
+    while (fgets(buf, (int) sizeof (buf), fp) != NULL) {
+        s = buf;
+        e = buf + (strlen(buf) - 1);
+
+        while(*e == ' ' ||  *e == '\n' || *e == '\t') {
+            e--;
+        }
+        *(e+1) ='\0';
+
+        while(*s != '\0' && (*s == ' ' || *s == '\t' || *s == '\n')) {
+            s++;
+        }
+
+        if (*s == '#' || *s == '\0') {
+            continue;
+        }
+        value = s + strcspn(s, " \t");
+        *value++ = '\0';
+
+        if(!strcmp(buf, key)) {
+            *env = value;
+            break;
+        }
+    }
+
+    fclose(fp);
+}
+
+static int create_subproc_thread(const char *name, int lines, int columns)
 {
     stinfo *sti;
     sdb_thread_t t;
     int ret_fd;
     pid_t pid;
+    char *value = NULL;
+    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 */
+        "DISPLAY=:0", /* without this, some programs based on without launchpad can't work */
+        NULL,
+        NULL,
+        NULL,
+        NULL,
+        NULL
+    };
 
-    if(name) {
-        ret_fd = create_subprocess(SHELL_COMMAND, "-c", name, &pid);
-    } else {
-        ret_fd = create_subprocess(SHELL_COMMAND, "-", 0, &pid);
+    if (should_drop_privileges()) {
+         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) {
+        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(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,
+            NULL,
+        };
+        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,
+                "-",
+                NULL,
+        };
+        ret_fd = create_subprocess(SHELL_COMMAND, &pid, args, envp);
+#if 0   // FIXME: should call login command instead of /bin/sh
+        if (should_drop_privileges()) {
+            char *args[] = {
+                SHELL_COMMAND,
+                "-",
+                NULL,
+            };
+            ret_fd = create_subprocess(SHELL_COMMAND, &pid, args, envp);
+        } else {
+            char *args[] = {
+                LOGIN_COMMAND,
+                "-f",
+                SUPER_USER,
+                NULL,
+            };
+            ret_fd = create_subprocess(LOGIN_COMMAND, &pid, args, envp);
+        }
+#endif
     }
     D("create_subprocess() ret_fd=%d pid=%d\n", ret_fd, pid);
 
@@ -501,6 +674,18 @@ static int create_subproc_thread(const char *name)
         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;
@@ -540,7 +725,7 @@ static int create_sync_subprocess(void (*func)(int, void *), void* cookie) {
         //waitpid(pid, &ret, 0);
     }
     if (pid < 0) {
-        D("- fork failed: %s -\n", strerror(errno));
+        D("- fork failed: errno:%d -\n", errno);
         sdb_close(s[0]);
         sdb_close(s[1]);
         D("cannot create sync service sub process\n");
@@ -584,25 +769,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_platform_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);
@@ -614,7 +787,7 @@ static void get_platforminfo(int fd, void *cookie) {
         }
     }
 
-    r = system_info_get_platform_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);
@@ -657,6 +830,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;
@@ -665,9 +964,22 @@ int service_to_fd(const char *name)
         int port = atoi(name + 4);
         name = strchr(name + 4, ':');
         if(name == 0) {
-            ret = socket_loopback_client(port, SOCK_STREAM);
-            if (ret >= 0)
+            if (is_emulator()){
+                ret = socket_ifr_client(port , SOCK_STREAM, "eth0");
+            } else {
+                ret = socket_ifr_client(port , SOCK_STREAM, "usb0");
+                if (ret < 0) {
+                    if (ifconfig(SDB_FORWARD_IFNAME, SDB_FORWARD_INTERNAL_IP, SDB_FORWARD_INTERNAL_MASK, 1) == 0) {
+                        ret = socket_ifr_client(port , SOCK_STREAM, SDB_FORWARD_IFNAME);
+                    }
+                }
+            }
+            if (ret < 0) {
+                ret = socket_loopback_client(port, SOCK_STREAM);
+            }
+            if (ret >= 0) {
                 disable_tcp_nagle(ret);
+            }
         } else {
 #if SDB_HOST
             sdb_mutex_lock(&dns_lock);
@@ -709,9 +1021,14 @@ int service_to_fd(const char *name)
         ret = create_service_thread(log_service, get_log_file_path(name + 4));
     }*/ else if(!HOST && !strncmp(name, "shell:", 6)) {
         if(name[6]) {
-            ret = create_subproc_thread(name + 6);
+            ret = create_subproc_thread(name + 6, 0, 0);
         } else {
-            ret = create_subproc_thread(0);
+            ret = create_subproc_thread(NULL, 0, 0);
+        }
+    } else if(!strncmp(name, "eshell:", 7)) {
+        int lines, columns;
+        if (sscanf(name+7, "%d:%d", &lines, &columns) == 2) {
+            ret = create_subproc_thread(NULL, lines, columns);
         }
     } else if(!strncmp(name, "sync:", 5)) {
         //ret = create_service_thread(file_sync_service, NULL);
@@ -731,22 +1048,27 @@ int service_to_fd(const char *name)
     } else if(!strncmp(name, "restore:", 8)) {
         ret = backup_service(RESTORE, NULL);
     }*/ else if(!strncmp(name, "root:", 5)) {
-        ret = create_service_thread(rootshell_service, (void *)(name+5));
-    } else if(!strncmp(name, "tcpip:", 6)) {
-        int port;
-        /*if (sscanf(name + 6, "%d", &port) == 0) {
-            port = 0;
-        }*/
-        port = DEFAULT_SDB_LOCAL_TRANSPORT_PORT;
-        ret = create_service_thread(restart_tcp_service, (void *)port);
-    } else if(!strncmp(name, "usb:", 4)) {
-        ret = create_service_thread(restart_usb_service, NULL);
+        char* service_name = NULL;
+
+        service_name = strdup(name+5);
+        ret = create_service_thread(rootshell_service, (void *)(service_name));
     } else if(!strncmp(name, "cs:", 5)) {
         ret = create_service_thread(inoti_service, NULL);
 #endif
     } else if(!strncmp(name, "sysinfo:", 8)){
         ret = create_service_thread(get_platforminfo, 0);
+    } 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 63d17ef..586a71a 100644 (file)
@@ -38,11 +38,11 @@ int socket_local_client(const char *name, int namespaceId, int type)
 #include <sys/types.h>
 
 #include "socket_local.h"
-
+#include "strutils.h"
 #define LISTEN_BACKLOG 4
 
 /* Documented in header file. */
-int socket_make_sockaddr_un(const char *name, int namespaceId, 
+int socket_make_sockaddr_un(const char *name, int namespaceId,
         struct sockaddr_un *p_addr, socklen_t *alen)
 {
     memset (p_addr, 0, sizeof (*p_addr));
@@ -62,7 +62,7 @@ int socket_make_sockaddr_un(const char *name, int namespaceId,
              * Note: The path in this case is *not* supposed to be
              * '\0'-terminated. ("man 7 unix" for the gory details.)
              */
-            
+
             p_addr->sun_path[0] = 0;
             memcpy(p_addr->sun_path + 1, name, namelen);
 #else /*HAVE_LINUX_LOCAL_SOCKET_NAMESPACE*/
@@ -70,37 +70,37 @@ int socket_make_sockaddr_un(const char *name, int namespaceId,
 
             namelen = strlen(name) + strlen(FILESYSTEM_SOCKET_PREFIX);
             /* unix_path_max appears to be missing on linux */
-            if (namelen > sizeof(*p_addr) 
+            if (namelen > sizeof(*p_addr)
                     - offsetof(struct sockaddr_un, sun_path) - 1) {
                 goto error;
             }
 
-            strcpy(p_addr->sun_path, FILESYSTEM_SOCKET_PREFIX);
-            strcat(p_addr->sun_path, name);
+            s_strncpy(p_addr->sun_path, FILESYSTEM_SOCKET_PREFIX, strlen(FILESYSTEM_SOCKET_PREFIX));
+            strncat(p_addr->sun_path, name, strlen(name));
 #endif /*HAVE_LINUX_LOCAL_SOCKET_NAMESPACE*/
         break;
 
         case ANDROID_SOCKET_NAMESPACE_RESERVED:
             namelen = strlen(name) + strlen(ANDROID_RESERVED_SOCKET_PREFIX);
             /* unix_path_max appears to be missing on linux */
-            if (namelen > sizeof(*p_addr) 
+            if (namelen > sizeof(*p_addr)
                     - offsetof(struct sockaddr_un, sun_path) - 1) {
                 goto error;
             }
 
-            strcpy(p_addr->sun_path, ANDROID_RESERVED_SOCKET_PREFIX);
-            strcat(p_addr->sun_path, name);
+            s_strncpy(p_addr->sun_path, ANDROID_RESERVED_SOCKET_PREFIX, strlen(ANDROID_RESERVED_SOCKET_PREFIX));
+            strncat(p_addr->sun_path, name, strlen(name));
         break;
 
         case ANDROID_SOCKET_NAMESPACE_FILESYSTEM:
             namelen = strlen(name);
             /* unix_path_max appears to be missing on linux */
-            if (namelen > sizeof(*p_addr) 
+            if (namelen > sizeof(*p_addr)
                     - offsetof(struct sockaddr_un, sun_path) - 1) {
                 goto error;
             }
 
-            strcpy(p_addr->sun_path, name);
+            s_strncpy(p_addr->sun_path, name, strlen(name));
         break;
         default:
             // invalid namespace id
@@ -118,10 +118,10 @@ error:
  * connect to peer named "name" on fd
  * returns same fd or -1 on error.
  * fd is not closed on error. that's your job.
- * 
+ *
  * Used by AndroidSocketImpl
  */
-int socket_local_client_connect(int fd, const char *name, int namespaceId, 
+int socket_local_client_connect(int fd, const char *name, int namespaceId,
         int type)
 {
     struct sockaddr_un addr;
@@ -144,7 +144,7 @@ error:
     return -1;
 }
 
-/** 
+/**
  * connect to peer named "name"
  * returns fd or -1 on error
  */
index 69fd87f..de229c1 100644 (file)
@@ -16,7 +16,7 @@
 // libs/cutils/socket_loopback_client.c
 
 #include "sockets.h"
-
+#include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
 #include <sys/select.h>
 #include <sys/types.h>
 #include <netinet/in.h>
+#include <sys/ioctl.h>
+#include <net/if.h>
+#include <arpa/inet.h>
 #endif
 
+#include "strutils.h"
 /* Connect to port on the loopback IP interface. type is
- * SOCK_STREAM or SOCK_DGRAM. 
+ * SOCK_STREAM or SOCK_DGRAM.
  * return is a file descriptor or -1 on error
  */
 int socket_loopback_client(int port, int type)
@@ -53,6 +57,94 @@ int socket_loopback_client(int port, int type)
     }
 
     return s;
+}
+
+int socket_ifr_client(int port, int type, char *ifr_dev)
+{
+    int s;
+    struct ifreq ifr;
+    struct sockaddr_in addr;
+
+    memset(&addr, 0, sizeof(addr));
+    addr.sin_family = AF_INET;
+    addr.sin_port = htons(port);
+
+    s = socket(AF_INET, SOCK_DGRAM, 0);
+    if(s < 0) {
+        return -1;
+    }
+    ifr.ifr_addr.sa_family = AF_INET;
+    s_strncpy(ifr.ifr_name, ifr_dev, IFNAMSIZ-1);
+
+    if (ioctl(s, SIOCGIFADDR, &ifr) < 0 ) {
+        close(s);
+        return -1;
+    }
+
+    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);
+
+    s = socket(AF_INET, type, 0);
+    if(s < 0) {
+        return -1;
+    }
+
+    if(connect(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
+        close(s);
+        return -1;
+    }
+
+    return s;
 }
 
+/* Simple implementation of ifconfig.
+ * activate: '0' causes the ifname driver to be shut down.
+ */
+int ifconfig(char *ifname, char *address, char *netmask, int activated) {
+    struct ifreq ifr;
+    struct sockaddr_in *sin;
+    int sockfd;
+
+    if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
+        fprintf(stderr, "cannot open socket\n");
+        return -1;
+    }
+
+    memset(&ifr, 0, sizeof(struct ifreq));
+    s_strncpy(ifr.ifr_name, ifname, IFNAMSIZ-1);
+
+    sin = (struct sockaddr_in *) &ifr.ifr_addr;
+    sin->sin_family = AF_INET;
+    sin->sin_port = 0;
+    sin->sin_addr.s_addr = inet_addr(address);
+
+    if (ioctl(sockfd, SIOCSIFADDR, &ifr) < 0) {
+        fprintf(stderr,"cannot set SIOCSIFADDR flags: %s(errno:%d)\n", address, errno);
+        close(sockfd);
+        return -1;
+    }
+
+    sin->sin_addr.s_addr = inet_addr(netmask);
+    if (ioctl(sockfd, SIOCSIFNETMASK, &ifr) < 0) {
+        fprintf(stderr,"cannot set SIOCSIFNETMASK flags: %s(errno:%d)\n", netmask, errno);
+        close(sockfd);
+        return -1;
+    }
+
+    if (activated) {
+        ifr.ifr_flags |= IFF_UP | IFF_RUNNING;
+    } else {
+        ifr.ifr_flags |= ~IFF_UP;
+    }
+    if (ioctl(sockfd, SIOCGIFFLAGS, &ifr) < 0) {
+        fprintf(stderr,"cannot set SIOCGIFFLAGS flags: errno:%d\n", errno);
+        close(sockfd);
+        return -1;
+    }
+
+    close(sockfd);
+    return 0;
+}
index d2b436a..326040b 100644 (file)
 
 
 /* Connect to port on the IP interface. type is
- * SOCK_STREAM or SOCK_DGRAM. 
+ * SOCK_STREAM or SOCK_DGRAM.
  * return is a file descriptor or -1 on error
  */
 int socket_network_client(const char *host, int port, int type)
 {
-    struct hostent *hp;
+    struct hostent hostbuf, *hp;
     struct sockaddr_in addr;
     int s;
+    size_t hstbuflen = 1024;
+    int res, herr;
+    char *tmphstbuf;
 
-    hp = gethostbyname(host);
-    if(hp == 0) return -1;
-    
+    tmphstbuf = malloc(hstbuflen);
+    if (tmphstbuf == NULL) {
+        return -1;
+    }
+
+    while ((res = gethostbyname_r(host, &hostbuf, tmphstbuf, hstbuflen, &hp, &herr)) == ERANGE) {
+        // enlarge the buffer
+        hstbuflen *= 2;
+        tmphstbuf = realloc(tmphstbuf, hstbuflen);
+        if (tmphstbuf == NULL) {
+            return -1;
+        }
+    }
+    if (res || hp == NULL) {
+        if (tmphstbuf != NULL) {
+            free(tmphstbuf);
+        }
+        return -1;
+    }
     memset(&addr, 0, sizeof(addr));
     addr.sin_family = hp->h_addrtype;
     addr.sin_port = htons(port);
     memcpy(&addr.sin_addr, hp->h_addr, hp->h_length);
 
     s = socket(hp->h_addrtype, type, 0);
-    if(s < 0) return -1;
+    if(s < 0) {
+        if (tmphstbuf != NULL) {
+            free(tmphstbuf);
+        }
+        return -1;
+    }
 
     if(connect(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
         close(s);
+
+        if (tmphstbuf != NULL) {
+            free(tmphstbuf);
+        }
         return -1;
     }
-
+    if (tmphstbuf != NULL) {
+        free(tmphstbuf);
+    }
     return s;
 
 }
index c621f47..16e746e 100644 (file)
@@ -25,6 +25,7 @@
 
 #define  TRACE_TAG  TRACE_SOCKETS
 #include "sdb.h"
+#include "strutils.h"
 
 SDB_MUTEX_DEFINE( socket_list_lock );
 
@@ -152,7 +153,7 @@ static int local_socket_enqueue(asocket *s, apacket *p)
             continue;
         }
         if((r == 0) || (errno != EAGAIN)) {
-            D( "LS(%d): not ready, errno=%d: %s\n", s->id, errno, strerror(errno) );
+            D( "LS(%d): not ready, errno=%d\n", s->id, errno);
             s->close(s);
             return 1; /* not ready (error) */
         } else {
@@ -199,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);
 
@@ -216,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);
-    }
 }
 
 
@@ -428,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;
 }
 
@@ -554,7 +540,7 @@ void connect_to_remote(asocket *s, const char *destination)
     p->msg.command = A_OPEN;
     p->msg.arg0 = s->id;
     p->msg.data_length = len;
-    strcpy((char*) p->data, destination);
+    s_strncpy((char*) p->data, destination, len);
     send_packet(p, s->transport);
 }
 
index 8e8196a..de2269f 100644 (file)
@@ -83,18 +83,24 @@ static inline int android_get_control_socket(const char *name)
 // Normal filesystem namespace
 #define ANDROID_SOCKET_NAMESPACE_FILESYSTEM 2
 
+#define SDB_FORWARD_IFNAME "lo:sdb"
+#define SDB_FORWARD_INTERNAL_IP "192.168.129.3"
+#define SDB_FORWARD_INTERNAL_MASK "255.255.255.0"
+
 extern int socket_loopback_client(int port, int type);
 extern int socket_network_client(const char *host, int port, int type);
 extern int socket_loopback_server(int port, int type);
 extern int socket_local_server(const char *name, int namespaceId, int type);
 extern int socket_local_server_bind(int s, const char *name, int namespaceId);
-extern int socket_local_client_connect(int fd, 
+extern int socket_local_client_connect(int fd,
         const char *name, int namespaceId, int type);
 extern int socket_local_client(const char *name, int namespaceId, int type);
 extern int socket_inaddr_any_server(int port, int type);
-    
+
+int socket_ifr_client(int port, int type, char *ifr_dev);
+int ifconfig(char *ifname, char *address, char *netmask, int activated);
 #ifdef __cplusplus
 }
 #endif
 
-#endif /* __CUTILS_SOCKETS_H */ 
+#endif /* __CUTILS_SOCKETS_H */
index 934cbdb..910e3be 100644 (file)
 size_t tokenize(const char *str, const char *delim, char *tokens[], size_t max_tokens ) {
     int cnt = 0;
 
-    char tmp[PATH_MAX];
+    char tmp[PATH_MAX+1];
+    char *ptr;
 
     strncpy(tmp, str, PATH_MAX);
-    char *p = strtok(tmp, delim);
+    tmp[PATH_MAX] = '\0';
+
+    char *p = strtok_r(tmp, delim, &ptr);
     if (max_tokens < 1 || max_tokens > MAX_TOKENS) {
         max_tokens = 1;
     }
@@ -23,7 +26,7 @@ size_t tokenize(const char *str, const char *delim, char *tokens[], size_t max_t
     if (p != NULL) {
         tokens[cnt++] = strdup(p);
         while(cnt < max_tokens && p != NULL) {
-            p = strtok(NULL, delim);
+            p = strtok_r(NULL, delim, &ptr);
             if (p != NULL) {
                 tokens[cnt++] = strdup(p);
             }
@@ -69,12 +72,15 @@ int read_line(const int fd, char* ptr, const unsigned int maxlen)
  * strncpy(ntbs, source, sizeof(ntbs)-1);
  * ntbs[sizeof(ntbs)-1] = '\0'
  */
+
 char *s_strncpy(char *dest, const char *source, size_t n) {
+
     char *start = dest;
 
-    while (n && (*dest++ = *source++)) {
+    while(n && (*dest++ = *source++)) {
         n--;
     }
+
     if (n) {
         while (--n) {
             *dest++ = '\0';
@@ -82,4 +88,3 @@ char *s_strncpy(char *dest, const char *source, size_t n) {
     }
     return start;
 }
-
index 0b70222..d99a2d4 100644 (file)
@@ -293,6 +293,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 "/"
@@ -498,7 +499,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)
@@ -527,6 +531,8 @@ static __inline__  int  sdb_is_absolute_host_path( const char*  path )
     return path[0] == '/';
 }
 
+#include "strutils.h"
+
 static __inline__  char* ansi_to_utf8(const char *str)
 {
     // Not implement!
@@ -536,7 +542,7 @@ static __inline__  char* ansi_to_utf8(const char *str)
 
     len = strlen(str);
     utf8 = (char *)calloc(len+1, sizeof(char));
-    strcpy(utf8, str);
+    s_strncpy(utf8, str, strlen(str));
     return utf8;
 }
 
index 1d91b80..e63e5d6 100644 (file)
@@ -45,11 +45,13 @@ static void  dump_hex( const unsigned char*  ptr, size_t  len )
 
     if (len2 > MAX_DUMP_HEX_LEN) len2 = MAX_DUMP_HEX_LEN;
 
+    int pbSize = sizeof(buffer);
     for (nn = 0; nn < len2; nn++) {
-        sprintf(pb, "%02x", ptr[nn]);
+        snprintf(pb, pbSize,  "%02x", ptr[nn]);
         pb += 2;
+        pbSize -= 2;
     }
-    sprintf(pb++, " ");
+    *pb++ = ' ';
 
     for (nn = 0; nn < len2; nn++) {
         int  c = ptr[nn];
@@ -150,7 +152,7 @@ read_packet(int  fd, const char* name, apacket** ppacket)
             len -= r;
             p   += r;
         } else {
-            D("%s: read_packet (fd=%d), error ret=%d errno=%d: %s\n", name, fd, r, errno, strerror(errno));
+            D("%s: read_packet (fd=%d), error ret=%d errno=%d\n", name, fd, r, errno);
             if((r < 0) && (errno == EINTR)) continue;
             return -1;
         }
@@ -187,7 +189,7 @@ write_packet(int  fd, const char* name, apacket** ppacket)
             len -= r;
             p += r;
         } else {
-            D("%s: write_packet (fd=%d) error ret=%d errno=%d: %s\n", name, fd, r, errno, strerror(errno));
+            D("%s: write_packet (fd=%d) error ret=%d errno=%d\n", name, fd, r, errno);
             if((r < 0) && (errno == EINTR)) continue;
             return -1;
         }
@@ -533,8 +535,8 @@ transport_read_action(int  fd, struct tmsg*  m)
             p   += r;
         } else {
             if((r < 0) && (errno == EINTR)) continue;
-            D("transport_read_action: on fd %d, error %d: %s\n",
-              fd, errno, strerror(errno));
+            D("transport_read_action: on fd %d, error %d\n",
+              fd, errno);
             return -1;
         }
     }
@@ -555,8 +557,8 @@ transport_write_action(int  fd, struct tmsg*  m)
             p   += r;
         } else {
             if((r < 0) && (errno == EINTR)) continue;
-            D("transport_write_action: on fd %d, error %d: %s\n",
-              fd, errno, strerror(errno));
+            D("transport_write_action: on fd %d, error %d\n",
+              fd, errno);
             return -1;
         }
     }
@@ -886,6 +888,10 @@ void close_usb_devices()
 void register_socket_transport(int s, const char *serial, int port, int local, const char *device_name)
 {
     atransport *t = calloc(1, sizeof(atransport));
+    if (t == NULL) {
+        D("failed to allocate memory of transport struct\n");
+        return;
+    }
     char buff[32];
 
     if (!serial) {
@@ -977,24 +983,49 @@ void unregister_all_tcp_transports()
 
 #endif
 
-int get_connected_device_count(transport_type type) /* tizen specific */
+int get_connected_count(transport_type type) /* tizen specific */
 {
     int cnt = 0;
     atransport *t;
     sdb_mutex_lock(&transport_lock);
     for(t = transport_list.next; t != &transport_list; t = t->next) {
-        if (type == kTransportUsb && t->type == kTransportUsb)
+        if (type == kTransportAny || type == t->type)
             cnt++;
      }
     sdb_mutex_unlock(&transport_lock);
-    D("connected device count:%d\n",cnt);
+    if (type == kTransportUsb) {
+        D("connected device count:%d\n",cnt);
+    }
     return cnt;
 }
 
+void broadcast_transport(apacket *p)
+{
+    atransport *t;
+    sdb_mutex_lock(&transport_lock);
+    for(t = transport_list.next; t != &transport_list; t = t->next) {
+        D("broadcast device transport:%d\n", t->connection_state);
+        apacket* ap = get_apacket();
+        copy_packet(ap, p);
+
+        send_packet(ap, t);
+        if (is_pwlocked()) {
+            t->connection_state = CS_PWLOCK;
+        } else {
+            t->connection_state = CS_DEVICE;
+        }
+     }
+    sdb_mutex_unlock(&transport_lock);
+}
+
 void register_usb_transport(usb_handle *usb, const char *serial, unsigned writeable)
 {
-    atransport *t = calloc(1, sizeof(atransport));
     char device_name[256];
+    atransport *t = calloc(1, sizeof(atransport));
+    if (t == NULL) {
+        D("failed to allocate memory of transport struct\n");
+        return;
+    }
 
     D("transport: %p init'ing for usb_handle %p (sn='%s')\n", t, usb,
       serial ? serial : "");
@@ -1004,7 +1035,7 @@ void register_usb_transport(usb_handle *usb, const char *serial, unsigned writea
     }
 
     /* tizen specific */
-    sprintf(device_name, "device-%d",get_connected_device_count(kTransportUsb)+1);
+    snprintf(device_name, sizeof(device_name), "device-%d",get_connected_count(kTransportUsb)+1);
     t->device_name = strdup(device_name);
     register_transport(t);
 }
@@ -1042,7 +1073,7 @@ int readx(int fd, void *ptr, size_t len)
             p += r;
         } else {
             if (r < 0) {
-                D("readx: fd=%d error %d: %s\n", fd, errno, strerror(errno));
+                D("readx: fd=%d error %d\n", fd, errno);
                 if (errno == EINTR)
                     continue;
             } else {
@@ -1075,7 +1106,7 @@ int writex(int fd, const void *ptr, size_t len)
             p += r;
         } else {
             if (r < 0) {
-                D("writex: fd=%d error %d: %s\n", fd, errno, strerror(errno));
+                D("writex: fd=%d error %d\n", fd, errno);
                 if (errno == EINTR)
                     continue;
             } else {
index 743ef2d..8e8029b 100644 (file)
@@ -173,9 +173,9 @@ int get_devicename_from_shdmem(int port, char *device_name)
 
     vms = strstr((char*)shared_memory, VMS_PATH);
     if (vms != NULL)
-        strncpy(device_name, vms+strlen(VMS_PATH), DEVICENAME_MAX);
+        s_strncpy(device_name, vms+strlen(VMS_PATH), DEVICENAME_MAX);
     else
-        strncpy(device_name, DEFAULT_DEVICENAME, DEVICENAME_MAX);
+        s_strncpy(device_name, DEFAULT_DEVICENAME, DEVICENAME_MAX);
 
 #else /* _WIN32*/
     HANDLE hMapFile;
@@ -202,9 +202,9 @@ int get_devicename_from_shdmem(int port, char *device_name)
 
     vms = strstr((char*)pBuf, VMS_PATH);
     if (vms != NULL)
-        strncpy(device_name, vms+strlen(VMS_PATH), DEVICENAME_MAX);
+        s_strncpy(device_name, vms+strlen(VMS_PATH), DEVICENAME_MAX);
     else
-        strncpy(device_name, DEFAULT_DEVICENAME, DEVICENAME_MAX);
+        s_strncpy(device_name, DEFAULT_DEVICENAME, DEVICENAME_MAX);
     CloseHandle(hMapFile);
 #endif
     D("init device name %s on port %d\n", device_name, port);
@@ -253,7 +253,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;
 
@@ -261,6 +261,7 @@ static void *server_socket_thread(void * arg)
     serverfd = -1;
     for(;;) {
         if(serverfd == -1) {
+            // socket_inaddr_any_server returns -1 if there is any error
             serverfd = socket_inaddr_any_server(port, SOCK_STREAM);
             if(serverfd < 0) {
                 D("server: cannot bind socket yet\n");
@@ -280,14 +281,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");
             }
             disable_tcp_nagle(fd);
-            register_socket_transport(fd, "host", port, 1, NULL);
+
+            // 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);
+            }
         }
     }
     D("transport: server_socket_thread() exiting\n");
@@ -485,35 +493,170 @@ static int send_msg_to_host_from_guest(const char *hostname, int host_port, char
     return 0;
 }
 
-static void notify_sdbd_startup() {
+int connect_nonb(int sockfd, const struct sockaddr *saptr, socklen_t salen,
+        int nsec) {
+    int flags, n, error;
+    socklen_t len;
+    fd_set rset, wset;
+    struct timeval tval;
+
+    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: errno:%d\n",
+                     sockfd, errno);
+    }
+
+    error = 0;
+    if ((n = connect(sockfd, (struct sockaddr *) saptr, salen)) < 0)
+        if (errno != EINPROGRESS)
+            return (-1);
+
+    /* Do whatever we want while the connect is taking place. */
+
+    if (n == 0)
+        goto done;
+    /* connect completed immediately */
+
+    FD_ZERO(&rset);
+    FD_SET(sockfd, &rset);
+    wset = rset;
+    tval.tv_sec = nsec;
+    tval.tv_usec = 0;
+    if ((n = select(sockfd + 1, &rset, &wset, NULL, nsec ? &tval : NULL))
+            == 0) {
+        sdb_close(sockfd); /* timeout */
+        errno = ETIMEDOUT;
+        return (-1);
+    }
+    if (FD_ISSET(sockfd, &rset) || FD_ISSET(sockfd, &wset)) {
+        len = sizeof(error);
+        if (getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &error, &len) < 0)
+            return (-1); /* Solaris pending error */
+    } else
+        D("select error: sockfd not set\n");
+
+    done:
+    if(fcntl(sockfd, F_SETFL, flags) == -1) { /* restore file status flags */
+        D("failed to restore file status flag for socket %d\n",
+                 sockfd);
+    }
+
+    if (error) {
+        sdb_close(sockfd); /* just in case */
+        errno = error;
+        return (-1);
+    }
+    return (0);
+}
+
+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(host_ip);
+
+    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);
+    } else {
+        s=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
+    }
+    if (s < 0) {
+        D("could not create socket\n");
+        return -1;
+    }
+    ret = connect_nonb(s, (struct sockaddr*) &server, sizeof(server), connect_timeout);
+    if (ret < 0) {
+        D("could not connect to server\n");
+        sdb_close(s);
+        return -1;
+    }
+    if (writex(s, request, strlen(request)) != 0) {
+        D("could not send notification request to host\n");
+        sdb_close(s);
+        return -1;
+    }
+    sdb_close(s);
+    D("sent notification request to host\n");
+
+    return 0;
+}
+
+// send the "emulator" request to sdbserver
+static void notify_sdbd_startup_thread() {
     char                 buffer[512];
     char                 request[512];
 
-    SdbdCommandlineArgs *sdbd_args = &sdbd_commandline_args; /* alias */
+    SdbdCommandlineArgs *sdbd_args = &sdbd_commandline_args; // alias
 
     // send the request to sdbserver
-    const char *vm_name = sdbd_args->emulator.host;
-    int sdbd_port = sdbd_args->sdbd_port;
+    char vm_name[256]={0,};
+    char host_ip[256] = {0,};
+    char guest_ip[256] = {0,};
     int sensors_port = sdbd_args->sensors.port;
+    int emulator_port = sdbd_args->emulator.port;
 
-
-    if (sdbd_port <= 0 || vm_name == NULL) {
+    int r = get_emulator_name(vm_name, sizeof vm_name);
+    int time = 0;
+    //int try_limit_time = -1; // try_limit_time < 0 if unlimited
+    if (sensors_port < 0 || emulator_port < 0 || r < 0) {
         return;
     }
-
-    // tell qemu sdbd is just started with udp
-    char sensord_buf[16];
-    snprintf(sensord_buf, sizeof sensord_buf, "2\n");
-    if (send_msg_to_host_from_guest(sdbd_args->sensors.host, sensors_port, sensord_buf, IPPROTO_UDP) < 0) {
-        D("could not send sensord noti request\n");
+    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) {
+        // 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)\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 sdb server emulator's vms name and forward port
-    snprintf(request, sizeof request, "host:emulator:%d:%s", sdbd_port, vm_name);
-    snprintf(buffer, sizeof buffer, "%04x%s", strlen(request), request);
+        // tell qemu sdbd is just started with udp
+        if (send_msg_to_localhost_from_guest(host_ip, sensors_port, "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
+        // TODO: should we use host:emulator request? let's talk about this!
 
-    if (send_msg_to_host_from_guest(sdbd_args->sdb.host, sdbd_args->sdb.port, buffer, IPPROTO_TCP) < 0) {
-        D("could not send sdbd noti request. it might sdb server has not been started yet.\n");
+        if (!strncmp(host_ip, QEMU_FORWARD_IP, sizeof host_ip)) {
+            snprintf(request, sizeof request, "host:emulator:%d:%s", (emulator_port + 1), vm_name);
+        } else {
+            snprintf(request, sizeof request, "host:connect:%s:%d", guest_ip, DEFAULT_SDB_LOCAL_TRANSPORT_PORT);
+        }
+        D("[%s:%d] request:%s \n", __FUNCTION__, __LINE__, request);
+        snprintf(buffer, sizeof buffer, "%04x%s", strlen(request), request );
+
+        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:
+        time++;
+        sleep(1);
     }
 }
 
@@ -560,7 +703,11 @@ void local_init(int port)
         sdb_mutex_lock(&register_noti_lock);
         pthread_cond_wait(&noti_cond, &register_noti_lock);
 
-        notify_sdbd_startup();
+        // thread start
+        if(sdb_thread_create(&thr, notify_sdbd_startup_thread, NULL)) {
+            fatal("cannot create notify_sdbd_startup_thread");
+            //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 fa813fc..d2af0c4 100644 (file)
@@ -86,23 +86,23 @@ int linux_usb_write(usb_handle *h, const void *data, int len)
     D("about to write (fd=%d, len=%d)\n", h->fd, len);
     n = sdb_write(h->fd, data, len);
     if(n != len) {
-        D("ERROR: fd = %d, n = %d, errno = %d (%s)\n",
-            h->fd, n, errno, strerror(errno));
+        D("ERROR: fd = %d, n = %d, errno = %d\n",
+            h->fd, n, errno);
         return -1;
     }
     D("[ done fd=%d ]\n", h->fd);
     return 0;
 }
 
-int linux_usb_read(usb_handle *h, void *data, int len)
+int linux_usb_read(usb_handle *h, void *data, unsigned len)
 {
     int n;
 
     D("about to read (fd=%d, len=%d)\n", h->fd, len);
     n = sdb_read(h->fd, data, len);
     if(n != len) {
-        D("ERROR: fd = %d, n = %d, errno = %d (%s)\n",
-            h->fd, n, errno, strerror(errno));
+        D("ERROR: fd = %d, n = %d, errno = %d\n",
+            h->fd, n, errno);
         return -1;
     }
     D("[ done fd=%d ]\n", h->fd);
@@ -116,11 +116,16 @@ void linux_usb_init()
 //  int fd;
 
     h = calloc(1, sizeof(usb_handle));
+    if (h == NULL) {
+        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);
 
-    // Open the file /dev/android_sdb_enable to trigger 
+    // Open the file /dev/android_sdb_enable to trigger
     // the enabling of the sdb USB function in the kernel.
     // We never touch this file again - just leave it open
     // indefinitely so the kernel will know when we are running
index d8ba651..b111a16 100644 (file)
 #include <stdarg.h>
 #include <stdio.h>
 #include <string.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <sys/wait.h>
+#include <errno.h>
 
 #define STRING_MAXLEN 1024
 char*
@@ -119,7 +124,82 @@ char *str_trim(const char* string)
         e--;
 
     ret = strdup(s);
+    if(ret == NULL) {
+        return NULL;
+    }
     ret[e - s + 1] = 0;
 
     return  ret;
 }
+
+int spawn(char* program, char** arg_list)
+{
+    pid_t pid;
+    int ret;
+
+    if ((pid = fork()) < 0) {
+        fprintf(stderr, "couldn't fork: %d\n", errno);
+        exit(1);
+    } else if (pid == 0) {
+            if ((pid = fork()) < 0) {
+                fprintf(stderr, "couldn't fork: %d\n", errno);
+                exit(1);
+            } else if (pid > 0) {
+                // init takes the process, and the process is not able to be zombie
+                exit(0);
+            }
+            execvp (program, arg_list);
+            fprintf(stderr, "failed to spawn: never reach here!:%s\n", program);
+            exit(0);
+    }
+    if (waitpid(pid, &ret, 0) != pid) {
+        fprintf(stderr, "failed to wait pid\n");
+    }
+
+    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 3df520e..6904377 100644 (file)
@@ -35,7 +35,7 @@
  *
  *    if (p >= end) {
  *        overflow detected. note that 'temp' is
- *        zero-terminated for safety. 
+ *        zero-terminated for safety.
  *    }
  *    return strdup(temp);
  */
@@ -67,4 +67,13 @@ char*   buff_add  (char*  buff, char*  buffEnd, const char*  format, ... );
     char   _buff[_size], *_cursor=_buff, *_end = _cursor + (_size)
 
 char *str_trim(const char* string);
+
+/*
+ * spawn a process and returns the process id of the new spawned process.
+ * it is working as async.
+ */
+int spawn(char* program, char** arg_list);
+
+char** str_split(char* a_str, const char a_delim);
+
 #endif /* _SDB_UTILS_H */