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
src/sockets.c
src/services.c
src/file_sync_service.c
+ src/usb_linux_client.c
src/utils.c
src/socket_inaddr_any_server.c
src/socket_local_client.c
src/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
)
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)
--- /dev/null
+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
--- /dev/null
+5
\ No newline at end of file
--- /dev/null
+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
--- /dev/null
+#!/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
+
--- /dev/null
+usr/sbin/sdbd
+etc/init.d/sdbd
+etc/rc.d/rc3.d/S06sdbd
- 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>
--- /dev/null
+[Unit]
+Description=sdbd
+
+[Service]
+Type=forking
+PIDFile=/tmp/.sdbd.pid
+RemainAfterExit=yes
+ExecStart=/usr/sbin/sdbd
Name: sdbd
Summary: SDB daemon
-Version: 3.0.1
+Version: 3.0.2
Release: 0
License: Apache-2.0
Summary: SDB daemon
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.
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
%{_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
[Unit]
Description=sdbd
Requires=tizen-system-env.service
+After=tmp.mount
[Service]
Type=forking
PIDFile=/tmp/.sdbd.pid
RemainAfterExit=yes
ExecStart=/usr/sbin/sdbd
+
+[Install]
+WantedBy=multi-user.target
\ No newline at end of file
[Unit]
Description=sdbd
Before=sensord.service
+After=tmp.mount dbus.service
+#DefaultDependencies=false
[Service]
Type=forking
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
+
--- /dev/null
+#!/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
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
esac
done
+if [ "" != "$appid" ]
+then
+ launch_app_arg1=$appid
+else
+ launch_app_arg1=$pkgid.$exe
+fi
+
if [ "$mode" = "debug" ]
then
if [ "" != "$attach_id" ]
--- /dev/null
+<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>
*/
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)) {
*/
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;
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,
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,
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;
}
}
+ 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;
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;
}
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;
}
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';
// 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;
}
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;
}
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;
}
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;
}
} 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;
}
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;
}
#include "sdb.h"
#include "file_sync_service.h"
#include "sdktools.h"
+#include "sdbd_plugin.h"
#define SYNC_TIMEOUT 15
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{
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);
+ }
+ */
}
}
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);
}
D("sync notify child process exit\n");
exit(-1);
}
+ buffer[len] = '\0';
char *path = buffer;
path++;
path++;
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;
}
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);
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] = '/';
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
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);
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)
return -1;
}
sync_send_label_notify(noti_fd, path, 1);
+ sync_mediadb(path);
return 0;
fail:
}
#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;
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);
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;
} 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);
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;
}
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;
}
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) {
-/* -*- 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);
#include <grp.h>
#include <netdb.h>
#include <tzplatform_config.h>
+#include <pthread.h>
+#include <dlfcn.h>
#include "sysdeps.h"
#include "sdb.h"
#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
#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";
{
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);
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");
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);
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);
#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) {
return -1;
}
- s_strncpy(str, s + strlen(dest), len);
+ strncpy(str, s + strlen(dest), len);
+ str[len]='\0';
return len;
}
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;
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;
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;
// 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)
#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;
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;
}
}
#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;
}
}
+ 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
}
}
- 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");
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);
}
#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;
#if !SDB_HOST
if (daemonize() < 0)
- fatal("daemonize() failed: %.200s", strerror(errno));
+ fatal("daemonize() failed: errno:%d", errno);
#endif
start_device_log();
#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
*/
int closing;
- /* flag: quit adbd when both ends close the
- ** local service socket
- */
- int exit_on_close;
-
/* the asocket we are connected to
*/
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);
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);
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
#endif
+int is_pwlocked(void);
int should_drop_privileges(void);
int set_developer_privileges();
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);
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);
#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;
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"
--- /dev/null
+/*
+ * 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
#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(®ex, pkg_path_regx, REG_EXTENDED);
+ if (ret){
+ D("failed : recomp (error:%d)\n", ret);
+ return 0;
+ }
+
+ ret = regexec(®ex, path, 0, NULL, 0);
+ regfree(®ex);
+
+ 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;
}
}
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: {
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;
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++) {
#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*/
};
#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
}
#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;
}
#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;
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")) {
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);
}
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);
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) {
}
}
}
+ if (i + EVENT_SIZE + event->len < event->len) { // in case of integer overflow
+ break;
+ }
i += EVENT_SIZE + event->len;
}
}
#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;
}
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.
// """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)
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;
}
}
-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);
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;
//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");
#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);
}
}
- 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);
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;
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);
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);
} 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");
#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));
* 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*/
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
* 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;
return -1;
}
-/**
+/**
* connect to peer named "name"
* returns fd or -1 on error
*/
// 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)
}
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;
+}
/* 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;
}
#define TRACE_TAG TRACE_SOCKETS
#include "sdb.h"
+#include "strutils.h"
SDB_MUTEX_DEFINE( socket_list_lock );
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 {
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);
}
remove_socket(s);
free(s);
-
- if (exit_on_close) {
- D("local_socket_destroy: exiting\n");
- exit(1);
- }
}
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;
}
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);
}
// 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 */
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;
}
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);
}
* 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';
}
return start;
}
-
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <string.h>
+#include <time.h>
#define OS_PATH_SEPARATOR '/'
#define OS_PATH_SEPARATOR_STR "/"
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)
return path[0] == '/';
}
+#include "strutils.h"
+
static __inline__ char* ansi_to_utf8(const char *str)
{
// Not implement!
len = strlen(str);
utf8 = (char *)calloc(len+1, sizeof(char));
- strcpy(utf8, str);
+ s_strncpy(utf8, str, strlen(str));
return utf8;
}
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];
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;
}
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;
}
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;
}
}
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;
}
}
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) {
#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 : "");
}
/* 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);
}
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 {
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 {
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;
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);
static void *server_socket_thread(void * arg)
{
int serverfd, fd;
- struct sockaddr addr;
+ struct sockaddr_in addr;
socklen_t alen;
int port = (int)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");
pthread_cond_broadcast(¬i_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");
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);
}
}
sdb_mutex_lock(®ister_noti_lock);
pthread_cond_wait(¬i_cond, ®ister_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(®ister_noti_lock);
}
}
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;
}
}
continue;
}
- D("ERROR: n = %d, errno = %d (%s)\n",
- n, errno, strerror(errno));
+ D("ERROR: n = %d, errno = %d \n",
+ n, errno);
return -1;
}
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);
}
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);
// 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
#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*
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;
+}
+
*
* if (p >= end) {
* overflow detected. note that 'temp' is
- * zero-terminated for safety.
+ * zero-terminated for safety.
* }
* return strdup(temp);
*/
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 */