X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Fsdb.c;h=7b33f8a843b34071576dad0b65daf425a0e204c7;hb=refs%2Fheads%2Ftizen;hp=e282cedb44bcb88be26b07c4caeccef38e924e05;hpb=84bfce8dd67d9d74febaf5ef3c0fe0cd6ec16382;p=sdk%2Ftarget%2Fsdbd.git diff --git a/src/sdb.c b/src/sdb.c old mode 100644 new mode 100755 index e282ced..7b33f8a --- a/src/sdb.c +++ b/src/sdb.c @@ -14,7 +14,8 @@ * limitations under the License. */ -#define TRACE_TAG TRACE_SDB +//#define TRACE_TAG TRACE_SDB +#define LOG_TAG "SDBD_TRACE_SDB" #include #include @@ -31,29 +32,31 @@ #include #include #include +#include #include "sysdeps.h" #include "log.h" #include "sdb.h" #include "strutils.h" -#if !SDB_HOST #include "commandline_sdbd.h" -#endif #include "utils.h" #include "sdktools.h" #include "plugin.h" #include "sdbd_plugin.h" +#include "sdb_systemd.h" -#if !SDB_HOST -#include -#define SDB_PIDPATH "/tmp/.sdbd.pid" +#ifdef SUPPORT_ENCRYPT +#include "plugin_encrypt.h" #endif + +#include #include #include #include #define PROC_CMDLINE_PATH "/proc/cmdline" #define USB_SERIAL_PATH "/sys/class/usb_mode/usb0/iSerial" +#define APPID2PID_PATH "/usr/bin/appid2pid" #include #include @@ -66,7 +69,12 @@ SDB_MUTEX_DEFINE(zone_check_lock); SDB_MUTEX_DEFINE( D_lock ); #endif +#define SDB_LOGCONF_PATH "/tmp/.sdbdlog.conf" + int HOST = 0; +int exit_cleanup_required = 0; + +// sdk user uid_t g_sdk_user_id; gid_t g_sdk_group_id; char* g_sdk_home_dir = NULL; @@ -75,6 +83,12 @@ pcap g_capabilities; int rootshell_mode; // 0: sdk user, 1: root int booting_done; // 0: platform booting is in progess 1: platform booting is done +// root user +uid_t g_root_user_id; +gid_t g_root_group_id; +char* g_root_home_dir = NULL; +char* g_root_home_dir_env = NULL; + struct group_info { const char *name; @@ -87,14 +101,16 @@ struct group_info g_default_groups[] = { {"log", -1}, {NULL, -1} }; + #define SDB_DEFAULT_GROUPS_CNT ((sizeof(g_default_groups)/sizeof(g_default_groups[0]))-1) +#define BUF_SIZE 4096 int is_init_sdk_userinfo = 0; int is_pwlocked = 0; // 0 if unlocked, 1 otherwise -#if !SDB_HOST +int recovery_mode = 0; + SdbdCommandlineArgs sdbd_commandline_args; -#endif static int is_support_usbproto(); static int is_support_sockproto(); @@ -108,9 +124,6 @@ void (*usb_kick)(usb_handle *h) = NULL; int g_is_emulator = -1; int is_emulator(void) { -#if SDB_HOST - return 0; -#else if (g_is_emulator >= 0) { return g_is_emulator; } else { @@ -118,7 +131,64 @@ int is_emulator(void) { } return sdbd_commandline_args.emulator.host != NULL; -#endif +} + +int is_appid2pid_supported(void) { + + if (access(APPID2PID_PATH, F_OK) == 0) { + /* It is necessary to confirm that it is possible + * to run "appid2pid" in the sdk user/group privileges. */ + struct stat st; + if (stat(APPID2PID_PATH, &st) == 0) { + D("appid2pid uid=%d, gid=%d, mode=0x%x.\n", st.st_uid, st.st_gid, st.st_mode); + if ( (st.st_uid == STATIC_SDK_USER_ID && st.st_mode & S_IXUSR) + || (st.st_gid == STATIC_SDK_GROUP_ID && st.st_mode & S_IXGRP) + || (st.st_mode & S_IXOTH) ) { + D("appid2pid is supported.\n"); + return 1; + } + } + } else { + D("failed to access appid2pid file: %d\n", errno); + } + + D("appid2pid is NOT supported.\n"); + return 0; +} + +int is_netcoredbg_supported(void) { + + FILE *fp = fopen(NETCOREDBG_LOCATION, "r"); + if (fp) { + size_t len; + ssize_t num; + char *line = NULL; + + while ((num = getline(&line, &len, fp)) != -1) { + if (strstr(line, "NETCOREDBG") != NULL) { + snprintf(g_capabilities.netcoredbg_support, sizeof(g_capabilities.netcoredbg_support), + "%s", ENABLED); + free(line); + fclose(fp); + return 1; + } + free(line); + line = NULL; + } + fclose(fp); + } + return 0; +} + +const char* get_platfrom_architecture(void) { + void* void_pointer; + D("void pointer size: %zu", sizeof(void_pointer)); + // in 32 bit sizeof void* is 4 and in 64 bit its 8 + if((int)(sizeof(void_pointer)) == 4) + return BIT32; + if((int)(sizeof(void_pointer)) == 8) + return BIT64; + return UNKNOWN; } int is_container_enabled(void) { @@ -126,7 +196,7 @@ int is_container_enabled(void) { 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); + E("failed to get container information: %d\n", errno); return 0; } else { D("tizen container: %d\n", value); @@ -137,12 +207,6 @@ int is_container_enabled(void) { } } -void handle_sig_term(int sig) { -#ifdef SDB_PIDPATH - if (access(SDB_PIDPATH, F_OK) == 0) - sdb_unlink(SDB_PIDPATH); -#endif -} static const char *sdb_device_banner = "device"; @@ -168,9 +232,47 @@ void fatal_errno(const char *fmt, ...) exit(-1); } +static char* get_sdb_log_conf(const char* key) +{ + int fd; + char line[256] = {0,}; + char value[256] = {0,}; + + if (access(SDB_LOGCONF_PATH, F_OK)) { + return NULL; + } + + fd = unix_open(SDB_LOGCONF_PATH, O_RDONLY); + if (fd < 0) { + E("failed to open '%s' file: %d\n", SDB_LOGCONF_PATH, errno); + return NULL; + } + + if (read_line(fd, line, sizeof(line)) > 0) { + char* start = strstr(line, key); + if (start != NULL) { + // move one more character to remove '=', + // including the length of the key string + start = start + strlen(key) + 1; + char* end = strstr(start, " "); + if (end != NULL) { + strncpy(value, start, end - start); + } else { + strncpy(value, start, sizeof(value) - 1); + value[sizeof(value) - 1] = '\0'; + } + } else { + sdb_close(fd); + return NULL; + } + } + sdb_close(fd); + return strdup(value); +} + static int is_enable_sdbd_log() { - return (!strncmp(g_capabilities.log_enable, PLUGIN_RET_ENABLED, strlen(PLUGIN_RET_ENABLED))); + return (!strncmp(g_capabilities.log_enable, PLUGIN_RET_ENABLED, strlen(PLUGIN_RET_ENABLED)+1)); } int sdb_trace_mask; @@ -182,7 +284,8 @@ int sdb_trace_mask; */ void sdb_trace_init(void) { - const char* p = getenv("SDB_TRACE"); + char* ptr = get_sdb_log_conf("SDB_TRACE"); + const char* p; const char* q; static const struct { @@ -207,11 +310,13 @@ void sdb_trace_init(void) { NULL, 0 } }; - if (p == NULL) { + if (ptr == NULL) { if (is_enable_sdbd_log()) p = "all"; else return; + } else { + p = ptr; } /* use a comma/column/semi-colum/space separated list */ @@ -233,6 +338,7 @@ void sdb_trace_init(void) int flag = tags[tagn].flag; if (flag == 0) { sdb_trace_mask = ~0; + free(ptr); return; } sdb_trace_mask |= (1 << flag); @@ -243,9 +349,9 @@ void sdb_trace_init(void) if (*p) p++; } + free(ptr); } -#if !SDB_HOST /* * Implements SDB tracing inside the emulator. */ @@ -270,46 +376,25 @@ void sdb_trace_init(void) /* A handle to sdb-debug qemud service in the emulator. */ int sdb_debug_qemu = -1; -/* Initializes connection with the sdb-debug qemud service in the emulator. */ -#if 0 /* doen't support in Tizen */ -static int sdb_qemu_trace_init(void) -{ - char con_name[32]; - - if (sdb_debug_qemu >= 0) { - return 0; - } - - /* sdb debugging QEMUD service connection request. */ - snprintf(con_name, sizeof(con_name), "qemud:sdb-debug"); - sdb_debug_qemu = qemu_pipe_open(con_name); - return (sdb_debug_qemu >= 0) ? 0 : -1; -} - -void sdb_qemu_trace(const char* fmt, ...) -{ - va_list args; - va_start(args, fmt); - char msg[1024]; - - if (sdb_debug_qemu >= 0) { - vsnprintf(msg, sizeof(msg), fmt, args); - sdb_write(sdb_debug_qemu, msg, strlen(msg)); - } -} -#endif -#endif /* !SDB_HOST */ - apacket *get_apacket(void) { apacket *p = malloc(sizeof(apacket)); - if(p == 0) fatal("failed to allocate an apacket"); + if(p == 0) { + // free only being done to resolve SVACE issue. + free(p) ; + fatal("failed to allocate an apacket"); + } memset(p, 0, sizeof(apacket) - MAX_PAYLOAD); return p; } void put_apacket(apacket *p) { + int result = access((const char *) p, F_OK); + if ((result == -1) && (errno == EFAULT)) { + E("Invalid apacket = [0x%p]", p); + fatal("Invalid apacket = [0x%p]", p); + } if (p != NULL) { free(p); p = NULL; @@ -318,12 +403,12 @@ void put_apacket(apacket *p) void handle_online(void) { - D("sdb: online\n"); + I("sdb: online\n"); } void handle_offline(atransport *t) { - D("sdb: offline\n"); + I("sdb: offline\n"); //Close the associated usb run_transport_disconnects(t); } @@ -368,9 +453,153 @@ void print_packet(const char *label, apacket *p) } #endif +#ifdef SUPPORT_ENCRYPT +/* +desc. : 암호화 실패 메시지 전송 +parameter : [in] apacket* p : sdbd로 들어온 메시지 + [in] atransport *t : 현재 연결에 대한 atransport + [in] unsigned failed_value : 실패 값 +*/ +void send_encr_fail(apacket* p, atransport *t, unsigned failed_value){ + apacket* enc_p; + enc_p = get_apacket(); + enc_p->msg.command = A_ENCR; // 암호화 메시지 + enc_p->msg.arg0 = failed_value; // 실패값 + enc_p->msg.arg1 = p->msg.arg1; + send_packet(enc_p, t); + //put_apacket(enc_p); +} + +/* +desc. : 암호화 메시지 핸들링 +parameter : [in] apacket* p : sdbd로 들어온 메시지 + [in/out] atransport *t : 현재 연결에 대한 atransport +ret : 0 : 정상적으로 메시지 전송 + -1: 메시지 전송 실패 +*/ +int handle_encr_packet(apacket* p, atransport *t){ + static int sessionID = 0; + int retVal = 0; + apacket* enc_p = NULL; + + if(p->msg.arg0 == ENCR_SET_ON_REQ){ // hello 메시지인 경우 + t->sessionID = sessionID; + if((retVal = security_init(t->sessionID, NULL)) == 1){ // 암호화 handshaking을 위한 init + if(security_parse_server_hello(t->sessionID, p) == 1){ // hello 메시지 파싱 + I("security_parse_server_hello success\n"); + enc_p = get_apacket(); + if(security_gen_client_hello(t->sessionID, enc_p) == 1){ // hello 메시지 생성 + I("security_gen_client_hello success\n"); + enc_p->msg.command = A_ENCR; + enc_p->msg.arg0 = ENCR_SET_ON_REQ; + enc_p->msg.arg1 = p->msg.arg1; + sessionID++; + send_packet(enc_p, t); + } + else { // hello 메시지 생성 실패 + E("security_gen_client_hello error\n"); + send_encr_fail(p, t, ENCR_ON_FAIL); // 암호화 on 실패 메시지 전송 + t->encryption = ENCR_OFF; // 암호화 모드는 off + security_deinit(t->sessionID); + return -1; + } + } + else{ // hello 메시지 파싱 실패 + E("security_parse_server_hello error\n"); + send_encr_fail(p, t, ENCR_ON_FAIL); + t->encryption = ENCR_OFF; + security_deinit(t->sessionID); + + return -1; + } + } else { // init 실패 + E("security_init error\n"); + send_encr_fail(p, t, ENCR_ON_FAIL); + t->encryption = ENCR_OFF; + if (retVal == 0) + { + security_deinit(t->sessionID); + } + //here!! do security_deinit(), but when plugin pointer is null -> not deinit + return -1; + } + } + else if(p->msg.arg0 == ENCR_SET_ON_OK){ // ack 메시지인 경우 + if(security_parse_server_ack(t->sessionID, p) == 1){ // ack 메시지 파싱 + enc_p = get_apacket(); + if(security_gen_client_ack(t->sessionID, enc_p) == 1){ // ack 메시지 생성 + I("security_gen_client_ack success\n"); + enc_p->msg.command = A_ENCR; + enc_p->msg.arg0 = ENCR_SET_ON_OK; + enc_p->msg.arg1 = p->msg.arg1; + t->encryption = ENCR_ON; + send_packet(enc_p, t); + } + else { // ack 메시지 생성에 실패한 경우 + E("security_gen_client_ack error\n"); + send_encr_fail(p, t, ENCR_ON_FAIL); + t->encryption = ENCR_OFF; + security_deinit(t->sessionID); + return -1; + } + } + else { // ack 메시지 파싱에 실패한 경우 + E("security_parse_server_ack error\n"); + send_encr_fail(p, t, ENCR_ON_FAIL); + t->encryption = ENCR_OFF; + security_deinit(t->sessionID); + return -1; + } + } + else if(p->msg.arg0 == ENCR_SET_OFF){ // 암호화 모드 off 요청 메시지 + if(t->encryption == ENCR_ON && security_deinit(t->sessionID) == 1){ // 현재 암호화 모드가 on 상태인 경우 + enc_p = get_apacket(); + t->encryption = ENCR_OFF; // 현재 연결에 대한 암호화 모드 off + enc_p->msg.command = A_ENCR; + enc_p->msg.arg0 = ENCR_SET_OFF; + enc_p->msg.arg1 = p->msg.arg1; + send_packet(enc_p, t); + } + else { // 암호화 모드 off에 실패한 경우 + E("security_deinit error\n"); + send_encr_fail(p, t, ENCR_OFF_FAIL); // 암호화 모드 off 실패 메시지 전송 + return -1; + } + } + else if(p->msg.arg0 == ENCR_GET){ // 암호화 모드의 상태 요청 메시지인 경우 + enc_p = get_apacket(); + enc_p->msg.command = A_ENCR; + enc_p->msg.arg0 = ENCR_GET; // 암호화 모드 status get메시지 + enc_p->msg.arg1 = p->msg.arg1; + if(t->encryption == ENCR_ON){ // 암호화 모드가 on인 경우 + enc_p->msg.data_length = 13; + strncpy((char*)enc_p->data, "encryption:on", enc_p->msg.data_length + 1); // encryption:on 메시지 전송 + } else if(t->encryption == ENCR_OFF){ // 암호화 모드가 off인 경우 + enc_p->msg.data_length = 14; + strncpy((char*)enc_p->data, "encryption:off", enc_p->msg.data_length + 1); // encryption:off 메시지 전송 + } + send_packet(enc_p, t); + } + else if (p->msg.arg0 == ENCR_ON_FAIL) // 암호화 모드를 on 하는 도중 실패한 경우 받는 메시지 + { + t->encryption = ENCR_OFF; // 암호화 모드를 다시 off + E("encryption on failed\n"); + } + else if (p->msg.arg0 == ENCR_OFF_FAIL) // 암호화 모드를 off하는 도중 실패한 경우 받는 메시지 + { + //t->encryption = ENCR_ON; + E("encryption off failed\n"); + } + //put_apacket(enc_p); + return 0; + +} +#endif + + static void send_ready(unsigned local, unsigned remote, atransport *t) { - D("Calling send_ready \n"); + I("Calling send_ready \n"); apacket *p = get_apacket(); p->msg.command = A_OKAY; p->msg.arg0 = local; @@ -380,7 +609,7 @@ static void send_ready(unsigned local, unsigned remote, atransport *t) static void send_close(unsigned local, unsigned remote, atransport *t) { - D("Calling send_close \n"); + I("Calling send_close \n"); apacket *p = get_apacket(); p->msg.command = A_CLSE; p->msg.arg0 = local; @@ -390,12 +619,15 @@ static void send_close(unsigned local, unsigned remote, atransport *t) static void send_connect(atransport *t) { - D("Calling send_connect \n"); + I("Calling send_connect \n"); apacket *cp = get_apacket(); cp->msg.command = A_CNXN; cp->msg.arg0 = A_VERSION; +#ifdef SUPPORT_ENCRYPT + cp->msg.arg1 = MAX_PAYLOAD - 100; // connection 시, sdb server의 패킷 크기를 암호화 오버로드 만큼 줄임 +#else cp->msg.arg1 = MAX_PAYLOAD; - +#endif char device_name[256]={0,}; int r = 0; int status = 0; @@ -415,20 +647,20 @@ static void send_connect(atransport *t) snprintf((char*) cp->data, sizeof cp->data, "%s::%s::%d", sdb_device_banner, device_name, status); } - D("CNXN data:%s\n", (char*)cp->data); + if (extcmd != NULL) { + char extbuf[BUF_SIZE] = {0,}; + snprintf(extbuf, sizeof extbuf, "::%s", extcmd); + strncat((char*) cp->data, extbuf, sizeof(cp->data) - strlen((const char*)cp->data)- 1); + } cp->msg.data_length = strlen((char*) cp->data) + 1; + D("CNXN data: %s\n", (char*)cp->data); send_packet(cp, t); -#if SDB_HOST - /* XXX why sleep here? */ - // allow the device some time to respond to the connect message - sdb_sleep_ms(1000); -#endif } void send_device_status() { - D("broadcast device status\n"); + I("broadcast device status\n"); apacket* cp = get_apacket(); cp->msg.command = A_STAT; cp->msg.arg0 = is_pwlocked; @@ -472,7 +704,7 @@ static int get_str_cmdline(char *src, char *dest, char str[], int str_size) { int len = e-s-strlen(dest); if (len >= str_size) { - D("buffer size(%d) should be bigger than %d\n", str_size, len+1); + E("buffer size(%d) should be bigger than %d\n", str_size, len+1); return -1; } @@ -506,7 +738,7 @@ int get_device_name(char str[], int str_size) { char *value = NULL; 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); + E("fail to get system model:%d\n", errno); return -1; } else { s_strncpy(str, value, str_size); @@ -538,13 +770,13 @@ static int get_cmdline_value(char *split, char str[], int str_size) { int fd = unix_open(PROC_CMDLINE_PATH, O_RDONLY); if (fd < 0) { - D("fail to read /proc/cmdline\n"); + E("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); + E("could not get the (%s) value from cmdline\n", split); sdb_close(fd); return -1; } @@ -564,19 +796,19 @@ int get_emulator_guestip(char str[], int str_size) { s = socket(AF_INET, SOCK_DGRAM, 0); if(s < 0) { - D("socket error\n"); + E("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"); + E("ioctl hwaddr error\n"); sdb_close(s); return -1; } if(ioctl(s, SIOCGIFADDR, &ifr) < 0) { - D("ioctl addr error\n"); + E("ioctl addr error\n"); sdb_close(s); return -1; } @@ -613,28 +845,28 @@ void parse_banner(char *banner, atransport *t) } if(!strcmp(type, "bootloader")){ - D("setting connection_state to CS_BOOTLOADER\n"); + I("setting connection_state to CS_BOOTLOADER\n"); t->connection_state = CS_BOOTLOADER; update_transports(); return; } if(!strcmp(type, "device")) { - D("setting connection_state to CS_DEVICE\n"); + I("setting connection_state to CS_DEVICE\n"); t->connection_state = CS_DEVICE; update_transports(); return; } if(!strcmp(type, "recovery")) { - D("setting connection_state to CS_RECOVERY\n"); + I("setting connection_state to CS_RECOVERY\n"); t->connection_state = CS_RECOVERY; update_transports(); return; } if(!strcmp(type, "sideload")) { - D("setting connection_state to CS_SIDELOAD\n"); + I("setting connection_state to CS_SIDELOAD\n"); t->connection_state = CS_SIDELOAD; update_transports(); return; @@ -643,6 +875,18 @@ void parse_banner(char *banner, atransport *t) t->connection_state = CS_HOST; } +static void update_version(atransport *t, int version, size_t payload) +{ +#ifdef SUPPORT_ENCRYPT + size_t max_payload = MAX_PAYLOAD - 100; +#else + size_t max_payload = MAX_PAYLOAD; +#endif + t->protocol_version = min(version, A_VERSION); + t->max_payload = min(payload, max_payload); + D("update transport version. version=%x, max_payload=%zu\n", t->protocol_version, t->max_payload); +} + void handle_packet(apacket *p, atransport *t) { // Verify pointer p @@ -653,10 +897,10 @@ void handle_packet(apacket *p, atransport *t) asocket *s; - D("handle_packet() %c%c%c%c\n", ((char*) (&(p->msg.command)))[0], - ((char*) (&(p->msg.command)))[1], - ((char*) (&(p->msg.command)))[2], - ((char*) (&(p->msg.command)))[3]); +// D("handle_packet() %c%c%c%c\n", ((char*) (&(p->msg.command)))[0], +// ((char*) (&(p->msg.command)))[1], +// ((char*) (&(p->msg.command)))[2], +// ((char*) (&(p->msg.command)))[3]); print_packet("recv", p); @@ -678,6 +922,7 @@ void handle_packet(apacket *p, atransport *t) t->connection_state = CS_OFFLINE; handle_offline(t); } + update_version(t, p->msg.arg0, p->msg.arg1); parse_banner((char*) p->data, t); handle_online(); if(!HOST) send_connect(t); @@ -686,7 +931,7 @@ void handle_packet(apacket *p, atransport *t) case A_OPEN: /* OPEN(local-id, 0, "destination") */ if (request_lock_state_to_plugin(LOCKTYPE_PASSWORD) == 1 && 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); + E("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) { @@ -732,13 +977,20 @@ void handle_packet(apacket *p, atransport *t) p->len = p->msg.data_length; if(s->enqueue(s, p) == 0) { - D("Enqueue the socket\n"); + I("Enqueue the socket\n"); send_ready(s->id, rid, t); } return; } } break; +#ifdef SUPPORT_ENCRYPT + case A_ENCR: // 암호화 메시지인 경우 + if(t->connection_state != CS_OFFLINE) { + handle_encr_packet(p, t); + } + break; +#endif default: printf("handle_packet: what is %08x?!\n", p->msg.command); @@ -755,6 +1007,7 @@ alistener listener_list = { static void ss_listener_event_func(int _fd, unsigned ev, void *_l) { asocket *s; + int ret = -1; if(ev & FDE_READ) { struct sockaddr addr; @@ -765,7 +1018,10 @@ static void ss_listener_event_func(int _fd, unsigned ev, void *_l) fd = sdb_socket_accept(_fd, &addr, &alen); if(fd < 0) return; - sdb_socket_setbufsize(fd, CHUNK_SIZE); + ret = sdb_socket_setbufsize(fd, CHUNK_SIZE); + if (ret == -1) { + D("sdbd: sdb_socket_setbufsize failed (%d)\n", ret); + } s = create_local_socket(fd); if(s) { @@ -924,7 +1180,7 @@ static int install_listener(const char *local_name, const char *connect_to, atra } if (close_on_exec(l->fd) < 0) { - D("fail to close fd exec:%d\n",l->fd); + E("fail to close fd exec:%d\n",l->fd); } if(!strcmp(l->connect_to, "*smartsocket*")) { fdevent_install(&l->fde, l->fd, ss_listener_event_func, l); @@ -951,14 +1207,6 @@ nomem: return 0; } -#ifdef HAVE_WIN32_PROC -static BOOL WINAPI ctrlc_handler(DWORD type) -{ - exit(STATUS_CONTROL_C_EXIT); - return TRUE; -} -#endif - static void sdb_cleanup(void) { clear_sdbd_commandline_args(&sdbd_commandline_args); @@ -973,87 +1221,41 @@ static void sdb_cleanup(void) unload_sdbd_plugin(); } -void start_logging(void) +static void sdb_service_cleanup(void) { -#ifdef HAVE_WIN32_PROC - char temp[ MAX_PATH ]; - FILE* fnul; - FILE* flog; - - GetTempPath( sizeof(temp) - 8, temp ); - strcat( temp, "sdb.log" ); - - /* Win32 specific redirections */ - fnul = fopen( "NUL", "rt" ); - if (fnul != NULL) - stdin[0] = fnul[0]; - - flog = fopen( temp, "at" ); - if (flog == NULL) - flog = fnul; - - setvbuf( flog, NULL, _IONBF, 0 ); - - stdout[0] = flog[0]; - stderr[0] = flog[0]; - fprintf(stderr,"--- sdb starting (pid %d) ---\n", getpid()); -#else - int fd; - - fd = unix_open("/dev/null", O_RDONLY); - if (fd < 0) { - // hopefully not gonna happen - return; - } - dup2(fd, 0); - sdb_close(fd); - - fd = unix_open("/tmp/sdb.log", O_WRONLY | O_CREAT | O_APPEND, 0640); - if(fd < 0) { - fd = unix_open("/dev/null", O_WRONLY); - if (fd < 0) { - // hopefully not gonna happen - return; - } + if (exit_cleanup_required) + { + unload_sdbd_service_plugin(); } - dup2(fd, 1); - dup2(fd, 2); - sdb_close(fd); - fprintf(stderr,"--- sdb starting (pid %d) ---\n", getpid()); -#endif } -#if !SDB_HOST void start_device_log(void) { int fd; - char path[PATH_MAX] = {0, }; + char path[2*PATH_MAX] = {0, }; char path_folder[PATH_MAX] = {0, }; char path_file[PATH_MAX] = {0, }; struct tm now; time_t t; -// char value[PROPERTY_VALUE_MAX]; - const char* p_trace = getenv("SDB_TRACE"); - const char* p_path = getenv("SDBD_LOG_PATH"); + // read the trace mask from persistent property persist.sdb.trace_mask // give up if the property is not set or cannot be parsed -#if 0 /* tizen specific */ - property_get("persist.sdb.trace_mask", value, ""); - if (sscanf(value, "%x", &sdb_trace_mask) != 1) - return; -#endif - + char* p_trace = get_sdb_log_conf("SDB_TRACE"); if ((p_trace == NULL ) && !is_enable_sdbd_log()) { return; + } else { + free(p_trace); } - - if (p_path) + char* p_path = get_sdb_log_conf("SDBD_LOG_PATH"); + if (p_path) { snprintf(path_folder, sizeof(path_folder), "%s", p_path); - else if (g_capabilities.log_path[0] != '\0') + free(p_path); + } else if (g_capabilities.log_path[0] != '\0') { snprintf(path_folder, sizeof(path_folder), "%s", g_capabilities.log_path); - else + } else { return; + } tzset(); time(&t); @@ -1085,174 +1287,6 @@ void start_device_log(void) sdb_close(fd); } -int daemonize(void) { - - // set file creation mask to 0 - umask(0); - - switch (fork()) { - case -1: - return -1; - case 0: - break; - default: - _exit(0); - } -#ifdef SDB_PIDPATH - FILE *f = fopen(SDB_PIDPATH, "w"); - - if (f != NULL) { - fprintf(f, "%d\n", getpid()); - fclose(f); - } -#endif - if (setsid() == -1) - return -1; - - if (chdir("/") < 0) - D("sdbd: unable to change working directory to /\n"); - - return 0; -} -#endif - -#if SDB_HOST -int launch_server(int server_port) -{ -#ifdef HAVE_WIN32_PROC - /* we need to start the server in the background */ - /* we create a PIPE that will be used to wait for the server's "OK" */ - /* message since the pipe handles must be inheritable, we use a */ - /* security attribute */ - HANDLE pipe_read, pipe_write; - SECURITY_ATTRIBUTES sa; - STARTUPINFO startup; - PROCESS_INFORMATION pinfo; - char program_path[ MAX_PATH ]; - int ret; - - sa.nLength = sizeof(sa); - sa.lpSecurityDescriptor = NULL; - sa.bInheritHandle = TRUE; - - /* create pipe, and ensure its read handle isn't inheritable */ - ret = CreatePipe( &pipe_read, &pipe_write, &sa, 0 ); - if (!ret) { - fprintf(stderr, "CreatePipe() failure, error %ld\n", GetLastError() ); - return -1; - } - - SetHandleInformation( pipe_read, HANDLE_FLAG_INHERIT, 0 ); - - ZeroMemory( &startup, sizeof(startup) ); - startup.cb = sizeof(startup); - startup.hStdInput = GetStdHandle( STD_INPUT_HANDLE ); - startup.hStdOutput = pipe_write; - startup.hStdError = GetStdHandle( STD_ERROR_HANDLE ); - startup.dwFlags = STARTF_USESTDHANDLES; - - ZeroMemory( &pinfo, sizeof(pinfo) ); - - /* get path of current program */ - GetModuleFileName( NULL, program_path, sizeof(program_path) ); - - ret = CreateProcess( - program_path, /* program path */ - "sdb fork-server server", - /* the fork-server argument will set the - debug = 2 in the child */ - NULL, /* process handle is not inheritable */ - NULL, /* thread handle is not inheritable */ - TRUE, /* yes, inherit some handles */ - DETACHED_PROCESS, /* the new process doesn't have a console */ - NULL, /* use parent's environment block */ - NULL, /* use parent's starting directory */ - &startup, /* startup info, i.e. std handles */ - &pinfo ); - - CloseHandle( pipe_write ); - - if (!ret) { - fprintf(stderr, "CreateProcess failure, error %ld\n", GetLastError() ); - CloseHandle( pipe_read ); - return -1; - } - - CloseHandle( pinfo.hProcess ); - CloseHandle( pinfo.hThread ); - - /* wait for the "OK\n" message */ - { - char temp[3]; - DWORD count; - - ret = ReadFile( pipe_read, temp, 3, &count, NULL ); - CloseHandle( pipe_read ); - if ( !ret ) { - fprintf(stderr, "could not read ok from SDB Server, error = %ld\n", GetLastError() ); - return -1; - } - if (count != 3 || temp[0] != 'O' || temp[1] != 'K' || temp[2] != '\n') { - fprintf(stderr, "SDB server didn't ACK\n" ); - return -1; - } - } -#elif defined(HAVE_FORKEXEC) - char path[PATH_MAX]; - int fd[2]; - - // set up a pipe so the child can tell us when it is ready. - // fd[0] will be parent's end, and fd[1] will get mapped to stderr in the child. - if (pipe(fd)) { - fprintf(stderr, "pipe failed in launch_server, errno: %d\n", errno); - return -1; - } - get_my_path(path, PATH_MAX); - pid_t pid = fork(); - if(pid < 0) return -1; - - if (pid == 0) { - // child side of the fork - - // redirect stderr to the pipe - // we use stderr instead of stdout due to stdout's buffering behavior. - sdb_close(fd[0]); - dup2(fd[1], STDERR_FILENO); - sdb_close(fd[1]); - - // child process - int result = execl(path, "sdb", "fork-server", "server", NULL); - // this should not return - fprintf(stderr, "OOPS! execl returned %d, errno: %d\n", result, errno); - } else { - // parent side of the fork - - char temp[3]; - - temp[0] = 'A'; temp[1] = 'B'; temp[2] = 'C'; - // wait for the "OK\n" message - sdb_close(fd[1]); - int ret = sdb_read(fd[0], temp, 3); - int saved_errno = errno; - sdb_close(fd[0]); - if (ret < 0) { - fprintf(stderr, "could not read ok from SDB Server, errno = %d\n", saved_errno); - return -1; - } - if (ret != 3 || temp[0] != 'O' || temp[1] != 'K' || temp[2] != '\n') { - fprintf(stderr, "SDB server didn't ACK\n" ); - return -1; - } - - setsid(); - } -#else -#error "cannot implement background server start on this platform" -#endif - return 0; -} -#endif - /* Constructs a local name of form tcp:port. * target_str points to the target string, it's content will be overwritten. * target_size is the capacity of the target string. @@ -1263,7 +1297,6 @@ void build_local_name(char* target_str, size_t target_size, int server_port) snprintf(target_str, target_size, "tcp:%d", server_port); } -#if !SDB_HOST static void init_drop_privileges() { #ifdef _DROP_PRIVILEGE rootshell_mode = 0; @@ -1273,143 +1306,154 @@ static void init_drop_privileges() { } int should_drop_privileges() { - if (rootshell_mode == 1) { // if root, then don't drop - return 0; - } - return 1; + return !rootshell_mode; // if root, then don't drop } -#include -#include -#include +#include +#define BOOTING_DONE_PATH "/org/tizen/system" #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"); +#define BOOTING_DONE_INTERFACE "org.tizen.system.Booting" +#define SDBD_BOOT_INFO_FILE "/tmp/sdbd_boot_info" + +static GMainLoop *g_mainloop; + +static void booting_done_signal_subscriber(GDBusConnection *connection, + const gchar *sender, const gchar *path, const gchar *interface, + const gchar *signal, GVariant *parameters, gpointer user_data) +{ + if (g_strcmp0(signal, BOOTING_DONE_SIGNAL) != 0) { + D("received signal(%s) does not match the desired signal(%s)\n", + signal, BOOTING_DONE_SIGNAL); + return; + } + + D("received the \"%s\" signal\n", signal); + + booting_done = 1; + if (access(SDBD_BOOT_INFO_FILE, F_OK) == 0) { + I("booting is already done\n"); + } else { + FILE *info_file = fopen(SDBD_BOOT_INFO_FILE, "w"); + if (info_file != NULL) { + char* tmppath = realpath(SDBD_BOOT_INFO_FILE, NULL); + if (tmppath != NULL) { + if (strcmp(SDBD_BOOT_INFO_FILE, tmppath) == 0) { + fprintf(info_file, "%d", 1); + I("booting is done\n"); + } else { + D("Path has symbolic link, security risk \n"); + free(tmppath); + return; + } + free(tmppath); } else { - FILE *f = fopen(SDBD_BOOT_INFO_FILE, "w"); - if (f != NULL) { - fprintf(f, "%d", 1); - fclose(f); - } + D("Getting realpath failed\n"); } - D("booting is done\n"); - } + fclose(info_file); + } + } - D("handled dbus message\n"); - return DBUS_HANDLER_RESULT_HANDLED; + I("handled the booting done signal\n"); + g_main_loop_quit(g_mainloop); } -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() is deprecated for glib version 2.35.0 or greater, */ -#if !GLIB_CHECK_VERSION(2,35,0) - g_type_init(); -#endif +static void *bootdone_cb(void *args) +{ + GError *error = NULL; + GDBusConnection *connection = NULL; + guint id; + + connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error); + if (connection == NULL) { + if (error != NULL) { + E("failed to connect to the system bus: %s\n", error->message); + g_error_free(error); + } else { + E("failed to connect to the system bus\n"); + } + return NULL; + } - 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 NULL; - } - dbus_connection_setup_with_g_main(bus, NULL); + g_mainloop = g_main_loop_new(NULL, false); + if (g_mainloop == NULL) { + E("failed to create a g_main_loop\n"); + goto bootdone_out; + } - 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 NULL; - } + id = g_dbus_connection_signal_subscribe(connection, + NULL, BOOTING_DONE_INTERFACE, BOOTING_DONE_SIGNAL, + BOOTING_DONE_PATH, NULL, G_DBUS_SIGNAL_FLAGS_NONE, + booting_done_signal_subscriber, NULL, NULL); + if (id == 0) { + E("failed to subscribe to the booting done signal\n"); + goto bootdone_out; + } - if (dbus_connection_add_filter(bus, __sdbd_dbus_signal_filter, NULL, NULL) - == FALSE) - return NULL; + I("wait for the booting done signal\n"); + g_main_loop_run(g_mainloop); - D("booting signal initialized\n"); - mainloop = g_main_loop_new(NULL, FALSE); - g_main_loop_run(mainloop); + g_dbus_connection_signal_unsubscribe(connection, id); - D("dbus loop exited"); +bootdone_out: + if (g_mainloop != NULL) { + g_main_loop_unref(g_mainloop); + } + if (connection != NULL) { + g_object_unref(connection); + } + I("exit the bootdone_cb thread\n"); - return NULL; + return NULL; } -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; - } +void register_bootdone_cb() +{ + sdb_thread_t t; + if (sdb_thread_create(&t, bootdone_cb, NULL)) { + E("can not create a service thread to check the booting done\n"); + return; + } + I("created the bootdone_cb thread\n"); } -static int sdbd_set_groups() { +static int sdbd_set_groups(const char *name, int gid, struct group_info default_groups[], int default_groups_size) { gid_t *group_ids = NULL; int ngroups = 0; int i, j = 0; int group_match = 0; int added_group_cnt = 0; - getgrouplist(SDK_USER_NAME, g_sdk_group_id, NULL, &ngroups); - D("group list : ngroups = %d\n", ngroups); - group_ids = malloc((ngroups + SDB_DEFAULT_GROUPS_CNT) * sizeof(gid_t)); + if (getgrouplist(name, gid, NULL, &ngroups) == -1) { + D("group list : ngroups = %d\n", ngroups); + } + group_ids = malloc((ngroups + default_groups_size) * sizeof(gid_t)); if (group_ids == NULL) { - D("failed to allocate group_ids(%d)\n", (ngroups + SDB_DEFAULT_GROUPS_CNT) * sizeof(gid_t)); + E("failed to allocate group_ids(%zu)\n", (ngroups + default_groups_size) * sizeof(gid_t)); return -1; } - if (getgrouplist(SDK_USER_NAME, g_sdk_group_id, group_ids, &ngroups) == -1) { - D("failed to getgrouplist(), ngroups = %d\n", ngroups); + if (getgrouplist(name, gid, group_ids, &ngroups) == -1) { + E("failed to getgrouplist(), ngroups = %d\n", ngroups); free(group_ids); return -1; } - - for (i = 0; g_default_groups[i].name != NULL; i++) { - for (j = 0; j < ngroups; j++) { - if (group_ids[j] == g_default_groups[i].gid) { - group_match = 1; - break; + if(default_groups_size >= 1) { + for (i = 0; default_groups[i].name != NULL; i++) { + for (j = 0; j < ngroups; j++) { + if (group_ids[j] == default_groups[i].gid) { + group_match = 1; + break; + } } + if (group_match == 0 && default_groups[i].gid != -1) { + group_ids[ngroups + added_group_cnt] = default_groups[i].gid; + added_group_cnt ++; + } + group_match = 0; } - if (group_match == 0 && g_default_groups[i].gid != -1) { - group_ids[ngroups + added_group_cnt] = g_default_groups[i].gid; - added_group_cnt ++; - } - group_match = 0; } - if (setgroups(ngroups+added_group_cnt, group_ids) != 0) { - D("failed to setgroups().\n"); + E("failed to setgroups().\n"); free(group_ids); return -1; } @@ -1425,10 +1469,10 @@ static int sdbd_get_user_pwd(const char* user_name, struct passwd* pwd, char* bu ret = getpwnam_r(user_name, pwd, buf, bufsize, &result); if (result == NULL) { if (ret == 0) { - D("Not found passwd : username(%s)\n", user_name); + E("Not found passwd : username(%s)\n", user_name); } else { errno = ret; - D("failed to getpwnam_r\n"); + E("failed to getpwnam_r\n"); } return -1; } @@ -1443,10 +1487,10 @@ static int sdbd_get_group(const char* group_name, struct group* grp, char* buf, ret = getgrnam_r(group_name, grp, buf, bufsize, &result); if (result == NULL) { if (ret == 0) { - D("Not found group : groupname(%s)\n", group_name); + E("Not found group : groupname(%s)\n", group_name); } else { errno = ret; - D("failed to getgrnam_r\n"); + E("failed to getgrnam_r\n"); } return -1; } @@ -1454,29 +1498,44 @@ static int sdbd_get_group(const char* group_name, struct group* grp, char* buf, return 0; } -int set_sdk_user_privileges() { +int set_sdk_user_privileges(int is_drop_capability_after_fork) { if (!is_init_sdk_userinfo) { - D("failed to init sdk user information.\n"); + E("failed to init sdk user information.\n"); return -1; } - if (sdbd_set_groups() < 0) { - D("set groups failed (errno: %d)\n", errno); + /* + * If a process switches its real, effective, or saved uids from at least one being 0 to all being non-zero, + * then both the permitted and effective capabilities are cleared. + */ + if(is_drop_capability_after_fork) { + + if (setuid(g_root_user_id) != 0) { + E("set root user id failed (errno: %d)\n", errno); + return -1; + } + } + + if (sdbd_set_groups(SDK_USER_NAME, g_sdk_group_id, g_default_groups, SDB_DEFAULT_GROUPS_CNT) < 0) { + E("set groups failed (errno: %d)\n", errno); return -1; } if (setgid(g_sdk_group_id) != 0) { - D("set group id failed (errno: %d)\n", errno); + E("set group id failed (errno: %d)\n", errno); return -1; } if (setuid(g_sdk_user_id) != 0) { - D("set user id failed (errno: %d)\n", errno); + E("set user id failed (errno: %d)\n", errno); return -1; +// if(is_drop_capability_after_fork) { +// return -1; +// } } if (chdir(g_sdk_home_dir) < 0) { - D("unable to change working directory to %s\n", g_sdk_home_dir); + E("unable to change working directory to %s\n", g_sdk_home_dir); } // TODO: use pam later @@ -1487,6 +1546,32 @@ int set_sdk_user_privileges() { return 0; } +int set_root_privileges() { + + if (sdbd_set_groups(ROOT_USER_NAME, g_root_group_id, NULL, 0) < 0) { + E("set root groups failed (errno: %d)\n", errno); + } + + if (setgid(g_root_group_id) != 0) { + E("set root group id failed (errno: %d)\n", errno); + } + + if (setuid(g_root_user_id) != 0) { + E("set root user id failed (errno: %d)\n", errno); + } + + if (chdir(g_root_home_dir) < 0) { + E("unable to change root working directory to %s\n", g_sdk_home_dir); + } + + // TODO: use pam later + if (g_root_home_dir_env) { + putenv(g_root_home_dir_env); + } + + return 0; +} + #define SDB_PW_GR_DEFAULT_SIZE (16*1024) static long get_passwd_bufsize() { long bufsize = 0; @@ -1519,7 +1604,7 @@ static int init_sdb_default_groups() { bufsize = get_group_bufsize(); buf = malloc(bufsize); if (buf == NULL) { - D("failed to allocate gruop buf(%ld)\n", bufsize); + E("failed to allocate gruop buf(%ld)\n", bufsize); return -1; } @@ -1528,7 +1613,7 @@ static int init_sdb_default_groups() { if (sdbd_get_group(g_default_groups[i].name, &grp, buf, bufsize) == 0) { g_default_groups[i].gid = grp.gr_gid; } else { - D("failed get group info.(errno: %d)\n", errno); + E("failed get group info.(errno: %d)\n", errno); } } @@ -1536,12 +1621,53 @@ static int init_sdb_default_groups() { return 0; } -static void set_static_userinfo() { +static void set_static_root_userinfo() { + g_root_user_id = STATIC_ROOT_USER_ID; + g_root_group_id = STATIC_ROOT_GROUP_ID; + g_root_home_dir = STATIC_ROOT_HOME_DIR; +} + +static void set_static_sdk_userinfo() { g_sdk_user_id = STATIC_SDK_USER_ID; g_sdk_group_id = STATIC_SDK_GROUP_ID; g_sdk_home_dir = STATIC_SDK_HOME_DIR; } +static int init_root_userinfo() { + struct passwd pwd; + char *buf = NULL; + long bufsize = 0; + + bufsize = get_passwd_bufsize(); + buf = malloc(bufsize); + if (buf == NULL) { + E("failed to allocate passwd buf(%ld)\n", bufsize); + set_static_root_userinfo(); + } else { + if (sdbd_get_user_pwd(ROOT_USER_NAME, &pwd, buf, bufsize) < 0) { + E("failed to get root user passwd info.(errno: %d)\n", errno); + set_static_root_userinfo(); + } else { + D("username=%s, uid=%d, gid=%d, dir=%s\n", pwd.pw_name, pwd.pw_uid, pwd.pw_gid, pwd.pw_dir); + + g_root_user_id = pwd.pw_uid; + g_root_group_id = pwd.pw_gid; + g_root_home_dir = strdup(pwd.pw_dir); + } + free(buf); + } + + int env_size = strlen("HOME=") + strlen(g_root_home_dir) + 1; + g_root_home_dir_env = malloc(env_size); + if(g_root_home_dir_env == NULL) { + E("failed to allocate for home dir env string\n"); + } else { + snprintf(g_root_home_dir_env, env_size, "HOME=%s", g_root_home_dir); + } + + return 0; +} + static int init_sdk_userinfo() { struct passwd pwd; char *buf = NULL; @@ -1552,18 +1678,18 @@ static int init_sdk_userinfo() { } if (init_sdb_default_groups() < 0) { - D("failed to initialize default groups.\n"); + E("failed to initialize default groups.\n"); } bufsize = get_passwd_bufsize(); buf = malloc(bufsize); if (buf == NULL) { - D("failed to allocate passwd buf(%ld)\n", bufsize); - set_static_userinfo(); + E("failed to allocate passwd buf(%ld)\n", bufsize); + set_static_sdk_userinfo(); } else { if (sdbd_get_user_pwd(SDK_USER_NAME, &pwd, buf, bufsize) < 0) { - D("get user passwd info.(errno: %d)\n", errno); - set_static_userinfo(); + E("get user passwd info.(errno: %d)\n", errno); + set_static_sdk_userinfo(); } else { D("username=%s, uid=%d, gid=%d, dir=%s\n", pwd.pw_name, pwd.pw_uid, pwd.pw_gid, pwd.pw_dir); @@ -1577,7 +1703,7 @@ static int init_sdk_userinfo() { int env_size = strlen("HOME=") + strlen(g_sdk_home_dir) + 1; g_sdk_home_dir_env = malloc(env_size); if(g_sdk_home_dir_env == NULL) { - D("failed to allocate for home dir env string\n"); + E("failed to allocate for home dir env string\n"); } else { snprintf(g_sdk_home_dir_env, env_size, "HOME=%s", g_sdk_home_dir); } @@ -1586,36 +1712,44 @@ static int init_sdk_userinfo() { return 0; } -static void init_sdk_requirements() { - struct stat st; +#if 0 +static int safe_system(char *cmd, char *argv[], char *envp[]) { + pid_t pid; + int status; - // set env variable for temporary - // TODO: should use pam instead later!! - if (!getenv("TERM")) { - putenv("TERM=linux"); + pid = fork(); + switch (pid) { + case -1: + return -1; + case 0: + execve(cmd, argv, envp); + E("- exec '%s' failed: (errno:%d) -\n", cmd, errno); + exit(-1); + default: + for (;;) { + pid_t p = waitpid(pid, &status, 0); + if (p == pid) { + break; + } + } } + return 0; +} +#endif - if (!getenv("HOME")) { - putenv("HOME=/root"); - } +static void init_sdk_requirements() { + // set env variable for temporary + // TODO: should use pam instead later!! + putenv("TERM=linux"); + putenv("HOME=/root"); init_sdk_userinfo(); - - if (g_sdk_home_dir != NULL && stat(g_sdk_home_dir, &st) == 0) { - if (st.st_uid != g_sdk_user_id || st.st_gid != g_sdk_group_id) { - char cmd[128]; - snprintf(cmd, sizeof(cmd), "chown %s:%s %s -R", SDK_USER_NAME, SDK_USER_NAME, g_sdk_home_dir); - if (system(cmd) < 0) { - D("failed to change ownership to sdk user to %s\n", g_sdk_home_dir); - } - } - } + init_root_userinfo(); if (is_emulator()) { register_bootdone_cb(); } } -#endif /* !SDB_HOST */ static void init_capabilities(void) { int ret = -1; @@ -1623,16 +1757,42 @@ static void init_capabilities(void) { memset(&g_capabilities, 0, sizeof(g_capabilities)); + // architecture support + char* arch = get_platfrom_architecture(); + snprintf(g_capabilities.architecture, sizeof(g_capabilities.architecture), + "%s", arch); + // CPU Architecture of model ret = system_info_get_platform_string("http://tizen.org/feature/platform.core.cpu.arch", &value); if (ret != SYSTEM_INFO_ERROR_NONE) { snprintf(g_capabilities.cpu_arch, sizeof(g_capabilities.cpu_arch), "%s", UNKNOWN); - D("fail to get the CPU architecture of model:%d\n", errno); + E("fail to get the CPU architecture of model:%d\n", errno); } else { - snprintf(g_capabilities.cpu_arch, sizeof(g_capabilities.cpu_arch), - "%s", value); if (value != NULL) { + // check for armv8 and 32 bit architecture, for it make the cpu arch as armv7l + if(!strncmp(value,"armv8",sizeof("armv8")+1) && !strncmp(arch,"32",sizeof("32")+1)) + { + D("Changing cpu arch in capability from %s to %s for %s bit\n",value,"armv7l",arch); + snprintf(g_capabilities.cpu_arch, sizeof(g_capabilities.cpu_arch), + "%s", "armv7l"); + } else { + snprintf(g_capabilities.cpu_arch, sizeof(g_capabilities.cpu_arch), + "%s", value); + } + free(value); + } + } + + // Core ABI (That value can be a "arm_32", "arm_64", "riscv_32", "riscv_64", "x86", "x86_64") + ret = system_info_get_platform_string("http://tizen.org/feature/platform.core.abi", &value); + if (ret != SYSTEM_INFO_ERROR_NONE) { + snprintf(g_capabilities.core_abi, sizeof(g_capabilities.core_abi), + "%s", UNKNOWN); + E("fail to get the core abi:%d\n", errno); + } else { + if (value != NULL) { + snprintf(g_capabilities.core_abi, sizeof(g_capabilities.core_abi), "%s", value); free(value); } } @@ -1641,7 +1801,7 @@ static void init_capabilities(void) { // Secure protocol support if(!request_capability_to_plugin(CAPABILITY_SECURE, g_capabilities.secure_protocol, sizeof(g_capabilities.secure_protocol))) { - D("failed to request. (%d:%d) \n", PLUGIN_SYNC_CMD_CAPABILITY, CAPABILITY_SECURE); + E("failed to request. (%d:%d) \n", PLUGIN_SYNC_CMD_CAPABILITY, CAPABILITY_SECURE); snprintf(g_capabilities.secure_protocol, sizeof(g_capabilities.secure_protocol), "%s", DISABLED); } @@ -1650,7 +1810,7 @@ static void init_capabilities(void) { // Interactive shell support if(!request_capability_to_plugin(CAPABILITY_INTER_SHELL, g_capabilities.intershell_support, sizeof(g_capabilities.intershell_support))) { - D("failed to request. (%d:%d) \n", PLUGIN_SYNC_CMD_CAPABILITY, CAPABILITY_INTER_SHELL); + E("failed to request. (%d:%d) \n", PLUGIN_SYNC_CMD_CAPABILITY, CAPABILITY_INTER_SHELL); snprintf(g_capabilities.intershell_support, sizeof(g_capabilities.intershell_support), "%s", DISABLED); } @@ -1659,7 +1819,7 @@ static void init_capabilities(void) { // File push/pull support if(!request_capability_to_plugin(CAPABILITY_FILESYNC, g_capabilities.filesync_support, sizeof(g_capabilities.filesync_support))) { - D("failed to request. (%d:%d) \n", PLUGIN_SYNC_CMD_CAPABILITY, CAPABILITY_FILESYNC); + E("failed to request. (%d:%d) \n", PLUGIN_SYNC_CMD_CAPABILITY, CAPABILITY_FILESYNC); snprintf(g_capabilities.filesync_support, sizeof(g_capabilities.filesync_support), "%s", DISABLED); } @@ -1668,7 +1828,7 @@ static void init_capabilities(void) { // USB protocol support if(!request_capability_to_plugin(CAPABILITY_USB_PROTOCOL, g_capabilities.usbproto_support, sizeof(g_capabilities.usbproto_support))) { - D("failed to request. (%d:%d) \n", PLUGIN_SYNC_CMD_CAPABILITY, CAPABILITY_USB_PROTOCOL); + E("failed to request. (%d:%d) \n", PLUGIN_SYNC_CMD_CAPABILITY, CAPABILITY_USB_PROTOCOL); snprintf(g_capabilities.usbproto_support, sizeof(g_capabilities.usbproto_support), "%s", DISABLED); } @@ -1677,21 +1837,33 @@ static void init_capabilities(void) { // Socket protocol support if(!request_capability_to_plugin(CAPABILITY_SOCK_PROTOCOL, g_capabilities.sockproto_support, sizeof(g_capabilities.sockproto_support))) { - D("failed to request. (%d:%d) \n", PLUGIN_SYNC_CMD_CAPABILITY, CAPABILITY_SOCK_PROTOCOL); + E("failed to request. (%d:%d) \n", PLUGIN_SYNC_CMD_CAPABILITY, CAPABILITY_SOCK_PROTOCOL); snprintf(g_capabilities.sockproto_support, sizeof(g_capabilities.sockproto_support), "%s", DISABLED); } + // Sdbd root permission + snprintf(g_capabilities.root_permission, sizeof(g_capabilities.root_permission), + "%s", DISABLED); // Root command support if(!request_capability_to_plugin(CAPABILITY_ROOT_ONOFF, g_capabilities.rootonoff_support, sizeof(g_capabilities.rootonoff_support))) { - D("failed to request. (%d:%d) \n", PLUGIN_SYNC_CMD_CAPABILITY, CAPABILITY_ROOT_ONOFF); + E("failed to request. (%d:%d) \n", PLUGIN_SYNC_CMD_CAPABILITY, CAPABILITY_ROOT_ONOFF); snprintf(g_capabilities.rootonoff_support, sizeof(g_capabilities.rootonoff_support), "%s", DISABLED); } + // Encryption support + if(!request_capability_to_plugin(CAPABILITY_ENCRYPTION, g_capabilities.encryption_support, + sizeof(g_capabilities.encryption_support))) { + E("failed to request. (%d:%d) \n", PLUGIN_SYNC_CMD_CAPABILITY, CAPABILITY_ENCRYPTION); + snprintf(g_capabilities.encryption_support, sizeof(g_capabilities.encryption_support), + "%s", DISABLED); + } + + // Zone support ret = is_container_enabled(); snprintf(g_capabilities.zone_support, sizeof(g_capabilities.zone_support), @@ -1716,7 +1888,7 @@ static void init_capabilities(void) { // SDK Tool path if (SDK_TOOL_PATH == NULL) { - D("fail to get SDK tool path.\n"); + E("fail to get SDK tool path.\n"); snprintf(g_capabilities.sdk_toolpath, sizeof(g_capabilities.sdk_toolpath), "%s", UNKNOWN); } else { @@ -1729,7 +1901,7 @@ static void init_capabilities(void) { 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); + E("fail to get profile name:%d\n", errno); } else { snprintf(g_capabilities.profile_name, sizeof(g_capabilities.profile_name), "%s", value); @@ -1744,7 +1916,7 @@ static void init_capabilities(void) { 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); + E("fail to get the Vendor name:%d\n", errno); } else { snprintf(g_capabilities.vendor_name, sizeof(g_capabilities.vendor_name), "%s", value); @@ -1755,21 +1927,35 @@ static void init_capabilities(void) { // Target name of the launch possible - if(!request_plugin_cmd(SDBD_CMD_PLUGIN_CAP, SDBD_CAP_TYPE_CANLAUNCH, - g_capabilities.can_launch, + if(!request_capability_to_plugin(CAPABILITY_CAN_LAUNCH, g_capabilities.can_launch, sizeof(g_capabilities.can_launch))) { - D("failed to request. (%s:%s) \n", SDBD_CMD_PLUGIN_CAP, SDBD_CAP_TYPE_CANLAUNCH); + E("failed to request. (%d:%d) \n", PLUGIN_SYNC_CMD_CAPABILITY, CAPABILITY_CAN_LAUNCH); snprintf(g_capabilities.can_launch, sizeof(g_capabilities.can_launch), "%s", UNKNOWN); } + // Device name + value = vconf_get_str(VCONFKEY_SETAPPL_DEVICE_NAME_STR); + if(value) { + snprintf(g_capabilities.device_name, sizeof(g_capabilities.device_name), + "%s", value); + if (value != NULL) { + free(value); + } + } else { + snprintf(g_capabilities.device_name, sizeof(g_capabilities.device_name), + "%s", UNKNOWN); + E("fail to get the Device name:%d\n", errno); + } + + // 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); + E("fail to get platform version:%d\n", errno); } else { snprintf(g_capabilities.platform_version, sizeof(g_capabilities.platform_version), "%s", value); @@ -1782,7 +1968,7 @@ static void init_capabilities(void) { // Product version if(!request_capability_to_plugin(CAPABILITY_PRODUCT_VER, g_capabilities.product_version, sizeof(g_capabilities.product_version))) { - D("failed to request. (%d:%d) \n", PLUGIN_SYNC_CMD_CAPABILITY, CAPABILITY_PRODUCT_VER); + E("failed to request. (%d:%d) \n", PLUGIN_SYNC_CMD_CAPABILITY, CAPABILITY_PRODUCT_VER); snprintf(g_capabilities.product_version, sizeof(g_capabilities.product_version), "%s", UNKNOWN); } @@ -1796,7 +1982,7 @@ static void init_capabilities(void) { // Sdbd plugin version if(!request_capability_to_plugin(CAPABILITY_PLUGIN_VER, g_capabilities.sdbd_plugin_version, sizeof(g_capabilities.sdbd_plugin_version))) { - D("failed to request. (%d:%d) \n", PLUGIN_SYNC_CMD_CAPABILITY, CAPABILITY_PLUGIN_VER); + E("failed to request. (%d:%d) \n", PLUGIN_SYNC_CMD_CAPABILITY, CAPABILITY_PLUGIN_VER); snprintf(g_capabilities.sdbd_plugin_version, sizeof(g_capabilities.sdbd_plugin_version), "%s", UNKNOWN); } @@ -1805,7 +1991,7 @@ static void init_capabilities(void) { // sdbd log enable if(!request_capability_to_plugin(CAPABILITY_LOG_ENABLE, g_capabilities.log_enable, sizeof(g_capabilities.log_enable))) { - D("failed to request. (%d:%d) \n", PLUGIN_SYNC_CMD_CAPABILITY, CAPABILITY_LOG_ENABLE); + E("failed to request. (%d:%d) \n", PLUGIN_SYNC_CMD_CAPABILITY, CAPABILITY_LOG_ENABLE); snprintf(g_capabilities.log_enable, sizeof(g_capabilities.log_enable), "%s", DISABLED); } @@ -1813,7 +1999,7 @@ static void init_capabilities(void) { // sdbd log path if(!request_capability_to_plugin(CAPABILITY_LOG_PATH, g_capabilities.log_path, sizeof(g_capabilities.log_path))) { - D("failed to request. (%d:%d) \n", PLUGIN_SYNC_CMD_CAPABILITY, CAPABILITY_LOG_PATH); + E("failed to request. (%d:%d) \n", PLUGIN_SYNC_CMD_CAPABILITY, CAPABILITY_LOG_PATH); snprintf(g_capabilities.log_path, sizeof(g_capabilities.log_path), "%s", UNKNOWN); } @@ -1821,11 +2007,29 @@ static void init_capabilities(void) { // Application command support if(!request_capability_to_plugin(CAPABILITY_APPCMD, g_capabilities.appcmd_support, sizeof(g_capabilities.appcmd_support))) { - D("failed to request. (%d:%d) \n", PLUGIN_SYNC_CMD_CAPABILITY, CAPABILITY_APPCMD); + E("failed to request. (%d:%d) \n", PLUGIN_SYNC_CMD_CAPABILITY, CAPABILITY_APPCMD); snprintf(g_capabilities.appcmd_support, sizeof(g_capabilities.appcmd_support), "%s", UNKNOWN); } + // appid2pid support + ret = is_appid2pid_supported(); + snprintf(g_capabilities.appid2pid_support, sizeof(g_capabilities.appid2pid_support), + "%s", ret == 1 ? ENABLED : DISABLED); + + // pkgcmd debug mode support + if(!request_capability_to_plugin(CAPABILITY_DEBUGMODE, g_capabilities.pkgcmd_debugmode, + sizeof(g_capabilities.pkgcmd_debugmode))) { + E("failed to request. (%d:%d) \n", PLUGIN_SYNC_CMD_CAPABILITY, CAPABILITY_DEBUGMODE); + snprintf(g_capabilities.pkgcmd_debugmode, sizeof(g_capabilities.pkgcmd_debugmode), + "%s", ENABLED); + } + + // netcore debugger support + ret = is_netcoredbg_supported(); + snprintf(g_capabilities.netcoredbg_support, sizeof(g_capabilities.netcoredbg_support), + "%s", ret == 1 ? ENABLED : DISABLED); + // Capability version snprintf(g_capabilities.sdbd_cap_version, sizeof(g_capabilities.sdbd_cap_version), "%d.%d", SDBD_CAP_VERSION_MAJOR, SDBD_CAP_VERSION_MINOR); @@ -1833,12 +2037,12 @@ static void init_capabilities(void) { static int is_support_usbproto() { - return (!strncmp(g_capabilities.usbproto_support, PLUGIN_RET_ENABLED, strlen(PLUGIN_RET_ENABLED))); + return (!strncmp(g_capabilities.usbproto_support, PLUGIN_RET_ENABLED, strlen(PLUGIN_RET_ENABLED)+1)); } static int is_support_sockproto() { - return (!strncmp(g_capabilities.sockproto_support, PLUGIN_RET_ENABLED, strlen(PLUGIN_RET_ENABLED))); + return (!strncmp(g_capabilities.sockproto_support, PLUGIN_RET_ENABLED, strlen(PLUGIN_RET_ENABLED)+1)); } #define EMULATOR_MODEL_NAME "Emulator" @@ -1850,16 +2054,16 @@ static void check_emulator_or_device() // Get the model name from model_config.xml ret = get_device_name(model_name, sizeof model_name); if (ret == 0) { - if(!strncmp(model_name, EMULATOR_MODEL_NAME, sizeof(EMULATOR_MODEL_NAME))){ + if(!strncmp(model_name, EMULATOR_MODEL_NAME, strlen("Emulator")+1)){ g_is_emulator = 1; - D("This target type is Emulator\n"); + I("This target type is Emulator\n"); } else { g_is_emulator = 0; - D("This target type is Device\n"); + I("This target type is Device\n"); } } else { g_is_emulator = -1; - D("failed to get the model name.\n"); + E("failed to get the model name.\n"); } } @@ -1878,52 +2082,36 @@ static void fork_child_handler(void) sdb_mutex_unlock(&D_lock); } -int sdb_main(int is_daemon, int server_port) +int sdb_main(int server_port) { -#if !SDB_HOST check_emulator_or_device(); load_sdbd_plugin(); init_capabilities(); - sdb_trace_init(); - start_device_log(); + //sdb_trace_init(); + //start_device_log(); init_drop_privileges(); init_sdk_requirements(); if (!request_validity_to_plugin(PLUGIN_SYNC_CMD_VERIFY_LAUNCH, NULL)) { - D("sdbd should be launched in develop mode.\n"); + E("sdbd should be launched in develop mode.\n"); return -1; } umask(000); pthread_atfork(fork_prepare_handler, fork_parent_handler, fork_child_handler); -#endif atexit(sdb_cleanup); -#ifdef HAVE_WIN32_PROC - SetConsoleCtrlHandler( ctrlc_handler, TRUE ); -#elif defined(HAVE_FORKEXEC) +#if defined(HAVE_FORKEXEC) // No SIGCHLD. Let the service subproc handle its children. signal(SIGPIPE, SIG_IGN); #endif init_transport_registration(); - -#if SDB_HOST - HOST = 1; - usb_init(); - local_init(DEFAULT_SDB_LOCAL_TRANSPORT_PORT); - - char local_name[30]; - build_local_name(local_name, sizeof(local_name), server_port); - if(install_listener(local_name, "*smartsocket*", NULL)) { - exit(1); - } -#else /* don't listen on a port (default 5037) if running in secure mode */ /* don't run as root if we are running in secure mode */ @@ -1959,7 +2147,7 @@ int sdb_main(int is_daemon, int server_port) cap.inheritable = 0; capset(&header, &cap); #endif - D("Local port disabled\n"); + I("Local port disabled\n"); } else { char local_name[30]; build_local_name(local_name, sizeof(local_name), server_port); @@ -2006,21 +2194,10 @@ int sdb_main(int is_daemon, int server_port) init_jdwp(); D("sdb_main(): post init_jdwp()\n"); #endif -#endif - if (is_daemon) - { - // inform our parent that we are up and running. -#ifdef HAVE_WIN32_PROC - DWORD count; - WriteFile( GetStdHandle( STD_OUTPUT_HANDLE ), "OK\n", 3, &count, NULL ); -#elif defined(HAVE_FORKEXEC) - fprintf(stderr, "OK\n"); -#endif - start_logging(); - } + sdb_notify_startup(0, "READY=1"); - D("Event loop starting\n"); + I("Event loop starting\n"); fdevent_loop(); @@ -2031,114 +2208,23 @@ int sdb_main(int is_daemon, int server_port) return 0; } -#if SDB_HOST -void connect_device(char* host, char* buffer, int buffer_size) +void sdb_main_service() { - int port, fd; - char* portstr = strchr(host, ':'); - char hostbuf[100]; - char serial[100]; - - s_strncpy(hostbuf, host, sizeof(hostbuf) - 1); - if (portstr) { - if (portstr - host >= sizeof(hostbuf)) { - snprintf(buffer, buffer_size, "bad host name %s", host); - return; - } - // zero terminate the host at the point we found the colon - hostbuf[portstr - host] = 0; - if (sscanf(portstr + 1, "%d", &port) == 0) { - snprintf(buffer, buffer_size, "bad port number %s", portstr); - return; - } - } else { - port = DEFAULT_SDB_LOCAL_TRANSPORT_PORT; - } - - snprintf(serial, sizeof(serial), "%s:%d", hostbuf, port); - if (find_transport(serial)) { - snprintf(buffer, buffer_size, "already connected to %s", serial); - return; - } - - fd = socket_network_client(hostbuf, port, SOCK_STREAM); - if (fd < 0) { - snprintf(buffer, buffer_size, "unable to connect to %s", host); - return; - } - - D("client: connected on remote on fd %d\n", fd); - close_on_exec(fd); - disable_tcp_nagle(fd); - register_socket_transport(fd, serial, port, 0, NULL); - snprintf(buffer, buffer_size, "connected to %s", serial); -} - -void connect_emulator(char* port_spec, char* buffer, int buffer_size) -{ - char* port_separator = strchr(port_spec, ','); - if (!port_separator) { - snprintf(buffer, buffer_size, - "unable to parse '%s' as ,", - port_spec); - return; - } - - // Zero-terminate console port and make port_separator point to 2nd port. - *port_separator++ = 0; - int console_port = strtol(port_spec, NULL, 0); - int sdb_port = strtol(port_separator, NULL, 0); - if (!(console_port > 0 && sdb_port > 0)) { - *(port_separator - 1) = ','; - snprintf(buffer, buffer_size, - "Invalid port numbers: Expected positive numbers, got '%s'", - port_spec); - return; - } - - /* Check if the emulator is already known. - * Note: There's a small but harmless race condition here: An emulator not - * present just yet could be registered by another invocation right - * after doing this check here. However, local_connect protects - * against double-registration too. From here, a better error message - * can be produced. In the case of the race condition, the very specific - * error message won't be shown, but the data doesn't get corrupted. */ - atransport* known_emulator = find_emulator_transport_by_sdb_port(sdb_port); - if (known_emulator != NULL) { - snprintf(buffer, buffer_size, - "Emulator on port %d already registered.", sdb_port); - return; - } - - /* Check if more emulators can be registered. Similar unproblematic - * race condition as above. */ - int candidate_slot = get_available_local_transport_index(); - if (candidate_slot < 0) { - snprintf(buffer, buffer_size, "Cannot accept more emulators."); - return; - } - - /* Preconditions met, try to connect to the emulator. */ - if (!local_connect_arbitrary_ports(console_port, sdb_port, NULL)) { - snprintf(buffer, buffer_size, - "Connected to emulator on ports %d,%d", console_port, sdb_port); - } else { - snprintf(buffer, buffer_size, - "Could not connect to emulator on ports %d,%d", - console_port, sdb_port); - } + load_sdbd_plugin(); + init_capabilities(); + init_sdk_requirements(); + atexit(sdb_service_cleanup); } -#endif int copy_packet(apacket* dest, apacket* src) { if(dest == NULL) { - D("dest packet is NULL\n"); + E("dest packet is NULL\n"); return -1; } if(src == NULL) { - D("src packet is NULL\n"); + E("src packet is NULL\n"); return -1; } @@ -2170,132 +2256,6 @@ int handle_host_request(char *service, transport_type ttype, char* serial, int r exit(0); } -#if SDB_HOST - // "transport:" is used for switching transport with a specified serial number - // "transport-usb:" is used for switching transport to the only USB transport - // "transport-local:" is used for switching transport to the only local transport - // "transport-any:" is used for switching transport to the only transport - if (!strncmp(service, "transport", strlen("transport"))) { - char* error_string = "unknown failure"; - transport_type type = kTransportAny; - - if (!strncmp(service, "transport-usb", strlen("transport-usb"))) { - type = kTransportUsb; - } else if (!strncmp(service, "transport-local", strlen("transport-local"))) { - type = kTransportLocal; - } else if (!strncmp(service, "transport-any", strlen("transport-any"))) { - type = kTransportAny; - } else if (!strncmp(service, "transport:", strlen("transport:"))) { - service += strlen("transport:"); - serial = service; - } - - transport = acquire_one_transport(CS_ANY, type, serial, &error_string); - - if (transport) { - s->transport = transport; - sdb_write(reply_fd, "OKAY", 4); - } else { - sendfailmsg(reply_fd, error_string); - } - return 1; - } - - // return a list of all connected devices - if (!strcmp(service, "devices")) { - char buffer[4096]; - memset(buf, 0, sizeof(buf)); - memset(buffer, 0, sizeof(buffer)); - D("Getting device list \n"); - list_transports(buffer, sizeof(buffer)); - snprintf(buf, sizeof(buf), "OKAY%04x%s",(unsigned)strlen(buffer),buffer); - D("Wrote device list \n"); - writex(reply_fd, buf, strlen(buf)); - return 0; - } - - // add a new TCP transport, device or emulator - if (!strncmp(service, "connect:", 8)) { - char buffer[4096]; - char* host = service + 8; - if (!strncmp(host, "emu:", 4)) { - connect_emulator(host + 4, buffer, sizeof(buffer)); - } else { - connect_device(host, buffer, sizeof(buffer)); - } - // Send response for emulator and device - snprintf(buf, sizeof(buf), "OKAY%04x%s",(unsigned)strlen(buffer), buffer); - writex(reply_fd, buf, strlen(buf)); - return 0; - } - - // remove TCP transport - if (!strncmp(service, "disconnect:", 11)) { - char buffer[4096]; - memset(buffer, 0, sizeof(buffer)); - char* serial = service + 11; - if (serial[0] == 0) { - // disconnect from all TCP devices - unregister_all_tcp_transports(); - } else { - char hostbuf[100]; - // assume port 26101 if no port is specified - if (!strchr(serial, ':')) { - snprintf(hostbuf, sizeof(hostbuf) - 1, "%s:26101", serial); - serial = hostbuf; - } - atransport *t = find_transport(serial); - - if (t) { - unregister_transport(t); - } else { - snprintf(buffer, sizeof(buffer), "No such device %s", serial); - } - } - - snprintf(buf, sizeof(buf), "OKAY%04x%s",(unsigned)strlen(buffer), buffer); - writex(reply_fd, buf, strlen(buf)); - return 0; - } - - // returns our value for SDB_SERVER_VERSION - if (!strcmp(service, "version")) { - char version[12]; - snprintf(version, sizeof version, "%04x", SDB_SERVER_VERSION); - snprintf(buf, sizeof buf, "OKAY%04x%s", (unsigned)strlen(version), version); - writex(reply_fd, buf, strlen(buf)); - return 0; - } - - if(!strncmp(service,"get-serialno",strlen("get-serialno"))) { - char *out = "unknown"; - transport = acquire_one_transport(CS_ANY, ttype, serial, NULL); - if (transport && transport->serial) { - out = transport->serial; - } - snprintf(buf, sizeof buf, "OKAY%04x%s",(unsigned)strlen(out),out); - writex(reply_fd, buf, strlen(buf)); - return 0; - } - // indicates a new emulator instance has started - if (!strncmp(service,"emulator:",9)) { /* tizen specific */ - char *tmp = strtok(service+9, DEVICEMAP_SEPARATOR); - int port = 0; - - if (tmp == NULL) { - port = atoi(service+9); - } else { - port = atoi(tmp); - tmp = strtok(NULL, DEVICEMAP_SEPARATOR); - if (tmp != NULL) { - local_connect(port, tmp); - } - } - local_connect(port, NULL); - return 0; - } -#endif // SDB_HOST - if(!strncmp(service,"forward:",8) || !strncmp(service,"killforward:",12)) { char *local, *remote, *err; int r; @@ -2350,56 +2310,3 @@ int handle_host_request(char *service, transport_type ttype, char* serial, int r } return -1; } - -#if !SDB_HOST -int recovery_mode = 0; -#endif - -int main(int argc, char **argv) -{ -#if SDB_HOST - sdb_sysdeps_init(); - sdb_trace_init(); - return sdb_commandline(argc - 1, argv + 1); -#else - /* If sdbd runs inside the emulator this will enable sdb tracing via - * sdb-debug qemud service in the emulator. */ -#if 0 /* tizen specific */ - sdb_qemu_trace_init(); - if((argc > 1) && (!strcmp(argv[1],"recovery"))) { - sdb_device_banner = "recovery"; - recovery_mode = 1; - } -#endif - - apply_sdbd_commandline_defaults(&sdbd_commandline_args); - int parse_ret = parse_sdbd_commandline(&sdbd_commandline_args, argc, argv); - - // TODO: Add detailed error messages - // TODO: Add individual messages for help and usage - if(parse_ret != SDBD_COMMANDLINE_SUCCESS) { - if (parse_ret == SDBD_COMMANDLINE_HELP - || parse_ret == SDBD_COMMANDLINE_USAGE) { - // User requested help or usage - print_sdbd_usage_message(stdout); - return EXIT_SUCCESS; - } - - // Print usage message because of invalid options - print_sdbd_usage_message(stderr); - return EXIT_FAILURE; - } - -#if !SDB_HOST - if (daemonize() < 0) - fatal("daemonize() failed: errno:%d", errno); -#endif - - D("Handling main()\n"); - - //sdbd will never die on emulator! - signal(SIGTERM, handle_sig_term); /* tizen specific */ - return sdb_main(0, DEFAULT_SDB_PORT); -#endif -} -