* limitations under the License.
*/
-#include <stdlib.h>
#include <stdio.h>
+#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include "sysdeps.h"
#define TRACE_TAG TRACE_SERVICES
+#include "log.h"
+
#include "sdb.h"
#include "file_sync_service.h"
# include <sys/ioctl.h>
# endif
#else
-# include "android_reboot.h"
# include <sys/inotify.h>
# include "sdktools.h"
#endif
+#include "strutils.h"
+#include "utils.h"
+#include <system_info.h>
+#include <tzplatform_config.h>
+
+#include <vconf.h>
+#include <limits.h>
+
+#include <termios.h>
+#include <sys/ioctl.h>
+
+#include "sdbd_plugin.h"
+#include "plugin.h"
+
typedef struct stinfo stinfo;
struct stinfo {
void *cookie;
};
-
void *service_bootstrap_func(void *x)
{
stinfo *sti = x;
}
#else
+static int is_support_interactive_shell()
+{
+ return (!strncmp(g_capabilities.intershell_support, PLUGIN_RET_ENABLED, strlen(PLUGIN_RET_ENABLED)));
+}
+
#if 0
extern int recovery_mode;
sdb_close(fd);
}
+static int is_support_rootonoff()
+{
+ return (!strncmp(g_capabilities.rootonoff_support, PLUGIN_RET_ENABLED, strlen(PLUGIN_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 sdk user 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")) {
if (rootshell_mode == 1) {
rootshell_mode = 0;
- snprintf(buf, sizeof(buf), "Switched to 'developer' account mode\n");
+ snprintf(buf, sizeof(buf), "Switched to 'sdk user' account mode\n");
writex(fd, buf, strlen(buf));
}
} else {
- snprintf(buf, sizeof(buf), "Unknown command option\n");
+ snprintf(buf, sizeof(buf), "Unknown command option : %s\n", mode);
writex(fd, buf, strlen(buf));
}
- D("set rootshell to %s\n", rootshell_mode == 1 ? "root" : "developer");
+ D("set rootshell to %s\n", rootshell_mode == 1 ? "root" : SDK_USER_NAME);
+ free(mode);
+ sdb_close(fd);
+}
+
+enum tzplatform_get_env_error_status {
+ NO_ERROR_TZPLATFORM_ENV = 0,
+ ERROR_TZPLATFORM_ENV_GENERAL = 1,
+ ERROR_TZPLATFORM_ENV_INVALID_VARIABLES = 2,
+};
+
+void get_tzplatform_env(int fd, void *cookie) {
+ char buf[PATH_MAX] = { 0, };
+ char *env_name = (char*) cookie;
+ D("environment variable name: %s\n", env_name);
+ enum tzplatform_variable env_id = tzplatform_getid(env_name);
+ if (env_id != _TZPLATFORM_VARIABLES_INVALID_) {
+ const char *env_value = tzplatform_getenv(env_id);
+ if (env_value) {
+ D("environment value : %s\n", env_value);
+ snprintf(buf, sizeof(buf), "%d%s", NO_ERROR_TZPLATFORM_ENV, env_value);
+ } else {
+ D("failed to get environment value using tzplatform_getenv");
+ snprintf(buf, sizeof(buf), "%d", ERROR_TZPLATFORM_ENV_GENERAL);
+ }
+ } else {
+ D("environment name (%s) is invalid\n", env_name);
+ snprintf(buf, sizeof(buf), "%d", ERROR_TZPLATFORM_ENV_INVALID_VARIABLES);
+ }
+ writex(fd, buf, strlen(buf));
+ free(env_name);
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);
#if !SDB_HOST
#define EVENT_SIZE ( sizeof (struct inotify_event) )
#define BUF_LEN ( 1024 * ( EVENT_SIZE + 16 ) )
-#define CS_PATH "/opt/usr/share/crash/report"
+#define CS_PATH tzplatform_getenv(TZ_SYS_CRASH)
void inoti_service(int fd, void *arg)
{
if ( ifd < 0 ) {
D( "inotify_init failed\n");
+ sdb_close(fd);
return;
}
wd = inotify_add_watch( ifd, CS_PATH, IN_CREATE);
+ if ( wd < 0 ) {
+ D("inotify_add_watch failed (errno :%d)\n", errno);
+ sdb_close(ifd);
+ sdb_close(fd);
+ return;
+ }
for ( ; ; ) {
int length, i = 0;
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, char * const argv[], char * const 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);
+}
+
+int create_subprocess(const char *cmd, pid_t *pid, char * const argv[], char * const 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_adj", getpid());
int fd = sdb_open(text, O_WRONLY);
if (fd >= 0) {
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_validity_to_plugin(PLUGIN_SYNC_CMD_VERIFY_ROOTCMD, argv[2])) {
+ // do nothing
+ D("sdb: executes root commands!!:%s\n", argv[2]);
+ } else {
+ if (getuid() != g_sdk_user_id && set_sdk_user_privileges() < 0) {
+ fprintf(stderr, "failed to set SDK user privileges\n");
+ exit(-1);
+ }
+ }
+ }
+ 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 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)
+void get_env(char *key, char **env)
+{
+ FILE *fp;
+ char buf[1024];
+ 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);
+
+ // trim string
+ while( (e > s) && (*e == ' ' || *e == '\n' || *e == '\t')) {
+ e--;
+ }
+ *(e+1) ='\0';
+
+ while(*s != '\0' && (*s == ' ' || *s == '\t' || *s == '\n')) {
+ s++;
+ }
+
+ // skip comment or null string
+ if (*s == '#' || *s == '\0') {
+ continue;
+ }
+ value = s + strcspn(s, " \t");
+ *value++ = '\0';
+
+ if(!strcmp(buf, key)) {
+ *env = strdup(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];
+ char *envp[MAX_TOKENS];
+ int envp_cnt = 0;
+
+ memset(path, 0, sizeof(path));
+ memset(envp, 0, sizeof(envp));
+
+ envp[envp_cnt++] = strdup("TERM=linux");
+ envp[envp_cnt++] = strdup("DISPLAY=:0");
+
+ if (should_drop_privileges()) {
+ if (g_sdk_home_dir_env) {
+ envp[envp_cnt++] = strdup(g_sdk_home_dir_env);
+ } else {
+ envp[envp_cnt++] = strdup("HOME=/home/owner");
+ }
+ get_env("ENV_PATH", &value);
+ } else {
+ get_env("ENV_SUPATH", &value);
+ if(value == NULL) {
+ get_env("ENV_ROOTPATH", &value);
+ }
+ envp[envp_cnt++] = strdup("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[envp_cnt++] = strdup(path);
+ } else {
+ snprintf(path, sizeof(path), "%s", value);
+ envp[envp_cnt++] = strdup(path);
+ }
+ free(value);
+ }
- if(name) {
- ret_fd = create_subprocess(SHELL_COMMAND, "-c", name, &pid);
+ /* get environment variables from plugin */
+ char *envp_plugin = NULL;
+ envp_plugin = malloc(SDBD_PLUGIN_OUTBUF_MAX);
+ if (envp_plugin == NULL) {
+ D("Cannot allocate the shell commnad buffer.");
+ return -1;
+ }
+ memset(envp_plugin, 0, SDBD_PLUGIN_OUTBUF_MAX);
+ if (!request_plugin_cmd(SDBD_CMD_SHELL_ENVVAR, "", envp_plugin, SDBD_PLUGIN_OUTBUF_MAX)) {
+ D("Failed to convert the shell command. (%s)\n", name);
+ free(envp_plugin);
+ return -1;
} else {
- ret_fd = create_subprocess(SHELL_COMMAND, "-", 0, &pid);
+ if(envp_plugin[0] != '\0') {
+ envp_cnt = tokenize_append(envp_plugin, "\n", envp, MAX_TOKENS, envp_cnt);
+ }
+ }
+ free(envp_plugin);
+
+ /* Last element of envp must be the NULL-terminator to prevent execvp fail */
+ envp[envp_cnt] = NULL;
+
+ if(name) { // in case of shell execution directly
+ // Check the shell command validation.
+ if (!request_validity_to_plugin(PLUGIN_SYNC_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_conversion_to_plugin(PLUGIN_SYNC_CMD_CONVERT_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, (char * const*)args, (char * const*)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 * const args[] = {
+ SHELL_COMMAND,
+ "-",
+ NULL,
+ };
+ ret_fd = create_subprocess(SHELL_COMMAND, &pid, (char * const*)args, (char * const*)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
+ }
+
+ /* free environment variables */
+ int i = 0;
+ if(envp_cnt > 0) {
+ for(i = 0; i < envp_cnt; i++) {
+ if(envp[i]) {
+ D("envp[%d] = %s\n", i, envp[i]);
+ free(envp[i]);
+ }
+ }
}
+
D("create_subprocess() ret_fd=%d pid=%d\n", ret_fd, pid);
if (ret_fd < 0) {
- printf("cannot create service thread\n");
+ 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;
if(sdb_thread_create( &t, service_bootstrap_func, sti)){
free(sti);
sdb_close(ret_fd);
- printf("cannot create service thread\n");
+ D("cannot create service thread\n");
return -1;
}
D("service thread started, fd=%d pid=%d\n",ret_fd, pid);
return ret_fd;
}
+
+static int create_sync_subprocess(void (*func)(int, void *), void* cookie) {
+ stinfo *sti;
+ sdb_thread_t t;
+ int s[2];
+
+ if(sdb_socketpair(s)) {
+ D("cannot create service socket pair\n");
+ return -1;
+ }
+
+ pid_t pid = fork();
+
+ if (pid == 0) {
+ sdb_close(s[0]);
+ func(s[1], cookie);
+ exit(-1);
+ } else if (pid > 0) {
+ sdb_close(s[1]);
+ // FIXME: do not wait child process hear
+ //waitpid(pid, &ret, 0);
+ }
+ if (pid < 0) {
+ D("- fork failed: errno:%d -\n", errno);
+ sdb_close(s[0]);
+ sdb_close(s[1]);
+ D("cannot create sync service sub process\n");
+ return -1;
+ }
+
+ sti = malloc(sizeof(stinfo));
+ if(sti == 0) fatal("cannot allocate stinfo");
+ sti->func = subproc_waiter_service;
+ sti->cookie = (void*)pid;
+ sti->fd = s[0];
+
+ if(sdb_thread_create( &t, service_bootstrap_func, sti)){
+ free(sti);
+ sdb_close(s[0]);
+ printf("cannot create service monitor thread\n");
+ return -1;
+ }
+
+ D("service process started, fd=%d pid=%d\n",s[0], pid);
+ return s[0];
+}
+
+static int create_syncproc_thread()
+{
+ int ret_fd;
+
+ ret_fd = create_sync_subprocess(file_sync_service, NULL);
+ // FIXME: file missing bug when root on mode
+ /*
+ if (should_drop_privileges()) {
+ ret_fd = create_sync_subprocess(file_sync_service, NULL);
+ } else {
+ ret_fd = create_service_thread(file_sync_service, NULL);
+ }
+ */
+
+ return ret_fd;
+}
#endif
+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("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);
+ } else {
+ s_strncpy(sysinfo.model_name, value, sizeof(sysinfo.model_name));
+ D("returns model_name:%s\n", value);
+ if (value != NULL) {
+ free(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);
+ } else {
+ s_strncpy(sysinfo.platform_name, value, sizeof(sysinfo.platform_name));
+ D("returns platform_name:%s\n", value);
+ if (value != NULL) {
+ free(value);
+ }
+
+ }
+
+ // FIXME: the result is different when using SYSTEM_INFO_KEY_TIZEN_VERSION_NAME
+ r = system_info_get_platform_string("tizen.org/feature/platform.version", &value);
+ if (r != SYSTEM_INFO_ERROR_NONE) {
+ s_strncpy(sysinfo.platform_version, UNKNOWN, strlen(UNKNOWN));
+ D("fail to get platform version:%d\n", errno);
+ } else {
+ s_strncpy(sysinfo.platform_version, value, sizeof(sysinfo.platform_version));
+ D("returns platform_version:%s\n", value);
+ if (value != NULL) {
+ free(value);
+ }
+ }
+
+ r = system_info_get_platform_string("tizen.org/feature/profile", &value);
+ if (r != SYSTEM_INFO_ERROR_NONE) {
+ s_strncpy(sysinfo.profile_name, UNKNOWN, strlen(UNKNOWN));
+ D("fail to get profile name:%d\n", errno);
+ } else {
+ s_strncpy(sysinfo.profile_name, value, sizeof(sysinfo.profile_name));
+ D("returns profile name:%s\n", value);
+ if (value != NULL) {
+ free(value);
+ }
+ }
+
+ writex(fd, &sysinfo, sizeof(pinfo));
+
+ 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);
+
+ // Window size synchronization support
+ offset += put_key_value_string(cap_buffer, offset, CAPBUF_SIZE,
+ "syncwinsz_support", g_capabilities.syncwinsz_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);
+
+ // SDK Tool path
+ offset += put_key_value_string(cap_buffer, offset, CAPBUF_SIZE,
+ "sdk_toolpath", g_capabilities.sdk_toolpath);
+
+ // 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);
+
+ // Target name of the launch possible
+ offset += put_key_value_string(cap_buffer, offset, CAPBUF_SIZE,
+ "can_launch", g_capabilities.can_launch);
+
+ // 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);
+
+ // Capability version
+ offset += put_key_value_string(cap_buffer, offset, CAPBUF_SIZE,
+ "sdbd_cap_version", g_capabilities.sdbd_cap_version);
+
+ // Sdbd log enable
+ offset += put_key_value_string(cap_buffer, offset, CAPBUF_SIZE,
+ "log_enable", g_capabilities.log_enable);
+
+ // Sdbd log path
+ offset += put_key_value_string(cap_buffer, offset, CAPBUF_SIZE,
+ "log_path", g_capabilities.log_path);
+
+ // Application command support
+ offset += put_key_value_string(cap_buffer, offset, CAPBUF_SIZE,
+ "appcmd_support", g_capabilities.appcmd_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, };
+ 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_subproc, NULL);
+ //ret = create_service_thread(file_sync_service, NULL);
+ ret = create_syncproc_thread();
}/* else if(!strncmp(name, "remount:", 8)) {
ret = create_service_thread(remount_service, NULL);
} else if(!strncmp(name, "reboot:", 7)) {
} 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
-#if 0
- } else if(!strncmp(name, "echo:", 5)){
- ret = create_service_thread(echo_service, 0);
-#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, (void *)name+20);
+ }
+ } else if(!strncmp(name, "tzplatformenv:", 14)) {
+ char* env_variable = NULL;
+ env_variable = strdup(name+14);
+ ret = create_service_thread(get_tzplatform_env, (void *)(env_variable));
+ } else if(!strncmp(name, "appcmd:", 7)){
+ ret = request_appcmd_to_plugin(name+7);
}
+
if (ret >= 0) {
if (close_on_exec(ret) < 0) {
D("failed to close fd exec\n");