[SATDEVKIT-2522]Symbolic link issues handled
[sdk/target/sdbd.git] / src / sdb.c
1 /*
2  * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the License);
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an AS IS BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 //#define  TRACE_TAG   TRACE_SDB
18 #define LOG_TAG "SDBD_TRACE_SDB"
19
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <ctype.h>
23 #include <stdarg.h>
24 #include <errno.h>
25 #include <string.h>
26 #include <time.h>
27 #include <sys/time.h>
28 #include <signal.h>
29 #include <grp.h>
30 #include <pwd.h>
31 #include <netdb.h>
32 #include <tzplatform_config.h>
33 #include <pthread.h>
34 #include <dlfcn.h>
35 #include <sys/smack.h>
36
37 #include "sysdeps.h"
38 #include "log.h"
39 #include "sdb.h"
40 #include "strutils.h"
41 #include "commandline_sdbd.h"
42 #include "utils.h"
43 #include "sdktools.h"
44 #include "plugin.h"
45 #include "sdbd_plugin.h"
46 #include "sdb_systemd.h"
47
48 #ifdef SUPPORT_ENCRYPT
49 #include "plugin_encrypt.h"
50 #endif
51
52 #include <linux/prctl.h>
53 #define SDB_PIDPATH "/tmp/.sdbd.pid"
54 #include <system_info.h>
55 #include <vconf.h>
56 #include <glib.h>
57
58 #define PROC_CMDLINE_PATH "/proc/cmdline"
59 #define USB_SERIAL_PATH "/sys/class/usb_mode/usb0/iSerial"
60 #define APPID2PID_PATH  "/usr/bin/appid2pid"
61
62 #include <sys/ioctl.h>
63 #include <net/if.h>
64 #include <netinet/in.h>
65 #include <arpa/inet.h>
66 #define GUEST_IP_INTERFACE "eth0"
67
68 SDB_MUTEX_DEFINE(zone_check_lock);
69 #if SDB_TRACE
70 SDB_MUTEX_DEFINE( D_lock );
71 #endif
72
73 #define SDB_LOGCONF_PATH "/tmp/.sdbdlog.conf"
74
75 int HOST = 0;
76
77 // sdk user
78 uid_t g_sdk_user_id;
79 gid_t g_sdk_group_id;
80 char* g_sdk_home_dir = NULL;
81 char* g_sdk_home_dir_env = NULL;
82 pcap g_capabilities;
83 int rootshell_mode; // 0: sdk user, 1: root
84 int booting_done; // 0: platform booting is in progess 1: platform booting is done
85
86 // root user
87 uid_t g_root_user_id;
88 gid_t g_root_group_id;
89 char* g_root_home_dir = NULL;
90 char* g_root_home_dir_env = NULL;
91
92 struct group_info
93 {
94     const char *name;
95     gid_t gid;
96 };
97 struct group_info g_default_groups[] = {
98     {"priv_externalstorage", -1},
99     {"priv_externalstorage_appdata", -1},
100     {"priv_mediastorage", -1},
101     {"log", -1},
102     {NULL, -1}
103 };
104
105 #define SDB_DEFAULT_GROUPS_CNT  ((sizeof(g_default_groups)/sizeof(g_default_groups[0]))-1)
106 #define BUF_SIZE 4096
107
108 int is_init_sdk_userinfo = 0;
109 int is_pwlocked = 0;    // 0 if unlocked, 1 otherwise
110
111 SdbdCommandlineArgs sdbd_commandline_args;
112
113 static int is_support_usbproto();
114 static int is_support_sockproto();
115
116 void (*usb_init)() = NULL;
117 void (*usb_cleanup)() = NULL;
118 int (*usb_write)(usb_handle *h, const void *data, int len) = NULL;
119 int (*usb_read)(usb_handle *h, void *data, size_t  len) = NULL;
120 int (*usb_close)(usb_handle *h) = NULL;
121 void (*usb_kick)(usb_handle *h) = NULL;
122
123 int g_is_emulator = -1;
124 int is_emulator(void) {
125     if (g_is_emulator >= 0) {
126         return g_is_emulator;
127     } else {
128         D("failed to initialize check emulator\n");
129     }
130
131     return sdbd_commandline_args.emulator.host != NULL;
132 }
133
134 int is_appid2pid_supported(void) {
135
136     if (access(APPID2PID_PATH, F_OK) == 0) {
137         /* It is necessary to confirm that it is possible
138          * to run "appid2pid" in the sdk user/group privileges. */
139         struct stat st;
140         if (stat(APPID2PID_PATH, &st) == 0) {
141             D("appid2pid uid=%d, gid=%d, mode=0x%x.\n", st.st_uid, st.st_gid, st.st_mode);
142             if ( (st.st_uid == STATIC_SDK_USER_ID && st.st_mode & S_IXUSR)
143                 || (st.st_gid == STATIC_SDK_GROUP_ID && st.st_mode & S_IXGRP)
144                 || (st.st_mode & S_IXOTH) ) {
145                 D("appid2pid is supported.\n");
146                 return 1;
147             }
148         }
149     } else {
150         D("failed to access appid2pid file: %d\n", errno);
151     }
152
153     D("appid2pid is NOT supported.\n");
154     return 0;
155 }
156
157 int is_netcoredbg_supported(void) {
158
159     FILE *fp = fopen(NETCOREDBG_LOCATION, "r");
160     if (fp) {
161         size_t len;
162         ssize_t num;
163         char *line = NULL;
164
165         while ((num = getline(&line, &len, fp)) != -1) {
166             if (strstr(line, "NETCOREDBG") != NULL) {
167                 snprintf(g_capabilities.netcoredbg_support, sizeof(g_capabilities.netcoredbg_support),
168                          "%s", ENABLED);
169                 free(line);
170                 return 1;
171             }
172             free(line);
173             line = NULL;
174         }
175         fclose(fp);
176     }
177     return 0;
178 }
179
180 int is_container_enabled(void) {
181     bool value;
182     int ret;
183     ret = system_info_get_platform_bool("tizen.org/feature/container", &value);
184     if (ret != SYSTEM_INFO_ERROR_NONE) {
185         E("failed to get container information: %d\n", errno);
186         return 0;
187     } else {
188         D("tizen container: %d\n", value);
189         if (value == true)
190             return 1;
191         else
192             return 0;
193     }
194 }
195
196 void handle_sig_term(int sig) {
197 #ifdef SDB_PIDPATH
198     if (access(SDB_PIDPATH, F_OK) == 0)
199         sdb_unlink(SDB_PIDPATH);
200 #endif
201 }
202
203 static const char *sdb_device_banner = "device";
204
205 void fatal(const char *fmt, ...)
206 {
207     va_list ap;
208     va_start(ap, fmt);
209     fprintf(stderr, "error: ");
210     vfprintf(stderr, fmt, ap);
211     fprintf(stderr, "\n");
212     va_end(ap);
213     exit(-1);
214 }
215
216 void fatal_errno(const char *fmt, ...)
217 {
218     va_list ap;
219     va_start(ap, fmt);
220     fprintf(stderr, "errno: %d: ", errno);
221     vfprintf(stderr, fmt, ap);
222     fprintf(stderr, "\n");
223     va_end(ap);
224     exit(-1);
225 }
226
227 static char* get_sdb_log_conf(const char* key)
228 {
229     int fd;
230     char line[256] = {0,};
231     char value[256] = {0,};
232
233     if (access(SDB_LOGCONF_PATH, F_OK)) {
234         return NULL;
235     }
236
237     fd = unix_open(SDB_LOGCONF_PATH, O_RDONLY);
238     if (fd < 0) {
239         E("failed to open '%s' file: %d\n", SDB_LOGCONF_PATH, errno);
240         return NULL;
241     }
242
243     if (read_line(fd, line, sizeof(line)) > 0) {
244         char* start = strstr(line, key);
245         if (start != NULL) {
246             // move one more character to remove '=',
247             // including the length of the key string
248             start = start + strlen(key) + 1;
249             char* end = strstr(start, " ");
250             if (end != NULL) {
251                 strncpy(value, start, end - start);
252             } else {
253                 strncpy(value, start, sizeof(value));
254             }
255         } else {
256             sdb_close(fd);
257             return NULL;
258         }
259     }
260     sdb_close(fd);
261     return strdup(value);
262 }
263
264 static int is_enable_sdbd_log()
265 {
266     return (!strncmp(g_capabilities.log_enable, PLUGIN_RET_ENABLED, strlen(PLUGIN_RET_ENABLED)));
267 }
268
269 int   sdb_trace_mask;
270
271 /* read a comma/space/colum/semi-column separated list of tags
272  * from the SDB_TRACE environment variable and build the trace
273  * mask from it. note that '1' and 'all' are special cases to
274  * enable all tracing
275  */
276 void  sdb_trace_init(void)
277 {
278     char*  ptr = get_sdb_log_conf("SDB_TRACE");
279     const char*  p;
280     const char*  q;
281
282     static const struct {
283         const char*  tag;
284         int           flag;
285     } tags[] = {
286         { "1", 0 },
287         { "all", 0 },
288         { "sdb", TRACE_SDB },
289         { "sockets", TRACE_SOCKETS },
290         { "packets", TRACE_PACKETS },
291         { "rwx", TRACE_RWX },
292         { "usb", TRACE_USB },
293         { "sync", TRACE_SYNC },
294         { "sysdeps", TRACE_SYSDEPS },
295         { "transport", TRACE_TRANSPORT },
296         { "jdwp", TRACE_JDWP },
297         { "services", TRACE_SERVICES },
298         { "properties", TRACE_PROPERTIES },
299         { "sdktools", TRACE_SDKTOOLS },
300         { "appcmd", TRACE_APPCMD },
301         { NULL, 0 }
302     };
303
304     if (ptr == NULL) {
305         if (is_enable_sdbd_log())
306             p = "all";
307         else
308             return;
309     } else {
310         p = ptr;
311     }
312
313     /* use a comma/column/semi-colum/space separated list */
314     while (*p) {
315         int  len, tagn;
316
317         q = strpbrk(p, " ,:;");
318         if (q == NULL) {
319             q = p + strlen(p);
320         }
321         len = q - p;
322
323         for (tagn = 0; tags[tagn].tag != NULL; tagn++)
324         {
325             int  taglen = strlen(tags[tagn].tag);
326
327             if (len == taglen && !memcmp(tags[tagn].tag, p, len) )
328             {
329                 int  flag = tags[tagn].flag;
330                 if (flag == 0) {
331                     sdb_trace_mask = ~0;
332                     free(ptr);
333                     return;
334                 }
335                 sdb_trace_mask |= (1 << flag);
336                 break;
337             }
338         }
339         p = q;
340         if (*p)
341             p++;
342     }
343     free(ptr);
344 }
345
346 /*
347  * Implements SDB tracing inside the emulator.
348  */
349
350 #include <stdarg.h>
351
352 /*
353  * Redefine open and write for qemu_pipe.h that contains inlined references
354  * to those routines. We will redifine them back after qemu_pipe.h inclusion.
355  */
356
357 #undef open
358 #undef write
359 #define open    sdb_open
360 #define write   sdb_write
361 #include "qemu_pipe.h"
362 #undef open
363 #undef write
364 #define open    ___xxx_open
365 #define write   ___xxx_write
366
367 /* A handle to sdb-debug qemud service in the emulator. */
368 int   sdb_debug_qemu = -1;
369
370 apacket *get_apacket(void)
371 {
372     apacket *p = malloc(sizeof(apacket));
373     if(p == 0) fatal("failed to allocate an apacket");
374     memset(p, 0, sizeof(apacket) - MAX_PAYLOAD);
375     return p;
376 }
377
378 void put_apacket(apacket *p)
379 {
380     if (p != NULL) {
381         free(p);
382         p = NULL;
383     }
384 }
385
386 void handle_online(void)
387 {
388     I("sdb: online\n");
389 }
390
391 void handle_offline(atransport *t)
392 {
393     I("sdb: offline\n");
394     //Close the associated usb
395     run_transport_disconnects(t);
396 }
397
398 #if TRACE_PACKETS
399 #define DUMPMAX 32
400 void print_packet(const char *label, apacket *p)
401 {
402     char *tag;
403     char *x;
404     unsigned count;
405
406     switch(p->msg.command){
407     case A_SYNC: tag = "SYNC"; break;
408     case A_CNXN: tag = "CNXN" ; break;
409     case A_OPEN: tag = "OPEN"; break;
410     case A_OKAY: tag = "OKAY"; break;
411     case A_CLSE: tag = "CLSE"; break;
412     case A_WRTE: tag = "WRTE"; break;
413     default: tag = "????"; break;
414     }
415
416     fprintf(stderr, "%s: %s %08x %08x %04x \"",
417             label, tag, p->msg.arg0, p->msg.arg1, p->msg.data_length);
418     count = p->msg.data_length;
419     x = (char*) p->data;
420     if(count > DUMPMAX) {
421         count = DUMPMAX;
422         tag = "\n";
423     } else {
424         tag = "\"\n";
425     }
426     while(count-- > 0){
427         if((*x >= ' ') && (*x < 127)) {
428             fputc(*x, stderr);
429         } else {
430             fputc('.', stderr);
431         }
432         x++;
433     }
434     fprintf(stderr, tag);
435 }
436 #endif
437
438 #ifdef SUPPORT_ENCRYPT
439 /*
440 desc. : 암호화 실패 메시지 전송
441 parameter : [in] apacket* p : sdbd로 들어온 메시지
442             [in] atransport *t : 현재 연결에 대한 atransport
443             [in] unsigned failed_value : 실패 값
444 */
445 void send_encr_fail(apacket* p, atransport *t, unsigned failed_value){
446     apacket* enc_p;
447     enc_p = get_apacket();
448     enc_p->msg.command = A_ENCR; // 암호화 메시지
449     enc_p->msg.arg0 = failed_value; // 실패값
450     enc_p->msg.arg1 = p->msg.arg1;
451     send_packet(enc_p, t);
452     //put_apacket(enc_p);
453 }
454
455 /*
456 desc. : 암호화 메시지 핸들링
457 parameter : [in] apacket* p : sdbd로 들어온 메시지
458             [in/out] atransport *t : 현재 연결에 대한 atransport
459 ret : 0 : 정상적으로 메시지 전송
460       -1: 메시지 전송 실패
461 */
462 int handle_encr_packet(apacket* p, atransport *t){
463     static int sessionID = 0;
464     int retVal = 0;
465     apacket* enc_p = NULL;
466
467     if(p->msg.arg0 == ENCR_SET_ON_REQ){ // hello 메시지인 경우
468         t->sessionID = sessionID;
469         if((retVal = security_init(t->sessionID, NULL)) == 1){ // 암호화 handshaking을 위한 init
470             if(security_parse_server_hello(t->sessionID, p) == 1){ // hello 메시지 파싱
471                 I("security_parse_server_hello success\n");
472                 enc_p = get_apacket();
473                 if(security_gen_client_hello(t->sessionID, enc_p) == 1){ // hello 메시지 생성
474                     I("security_gen_client_hello success\n");
475                     enc_p->msg.command = A_ENCR;
476                     enc_p->msg.arg0 = ENCR_SET_ON_REQ;
477                     enc_p->msg.arg1 = p->msg.arg1;
478                     sessionID++;
479                     send_packet(enc_p, t);
480                 }
481                 else { // hello 메시지 생성 실패
482                     E("security_gen_client_hello error\n");
483                     send_encr_fail(p, t, ENCR_ON_FAIL); // 암호화 on 실패 메시지 전송
484                     t->encryption = ENCR_OFF; // 암호화 모드는 off
485                     security_deinit(t->sessionID);
486                     return -1;
487                 }
488             }
489             else{ // hello 메시지 파싱 실패
490                 E("security_parse_server_hello error\n");
491                 send_encr_fail(p, t, ENCR_ON_FAIL);
492                 t->encryption = ENCR_OFF;
493                 security_deinit(t->sessionID);
494
495                 return -1;
496             }
497         } else { // init 실패
498             E("security_init error\n");
499             send_encr_fail(p, t, ENCR_ON_FAIL);
500             t->encryption = ENCR_OFF;
501             if (retVal == 0)
502             {
503                 security_deinit(t->sessionID);
504             }
505             //here!! do security_deinit(), but when plugin pointer is null -> not deinit
506             return -1;
507         }
508     }
509     else if(p->msg.arg0 == ENCR_SET_ON_OK){ // ack 메시지인 경우
510         if(security_parse_server_ack(t->sessionID, p) == 1){    // ack 메시지 파싱
511             enc_p = get_apacket();
512             if(security_gen_client_ack(t->sessionID, enc_p) == 1){ // ack 메시지 생성
513                 I("security_gen_client_ack success\n");
514                 enc_p->msg.command = A_ENCR;
515                 enc_p->msg.arg0 = ENCR_SET_ON_OK;
516                 enc_p->msg.arg1 = p->msg.arg1;
517                 t->encryption = ENCR_ON;
518                 send_packet(enc_p, t);
519             }
520             else { // ack 메시지 생성에 실패한 경우
521                 E("security_gen_client_ack error\n");
522                 send_encr_fail(p, t, ENCR_ON_FAIL);
523                 t->encryption = ENCR_OFF;
524                 security_deinit(t->sessionID);
525                 return -1;
526             }
527         }
528         else { // ack 메시지 파싱에 실패한 경우
529             E("security_parse_server_ack error\n");
530             send_encr_fail(p, t, ENCR_ON_FAIL);
531             t->encryption = ENCR_OFF;
532             security_deinit(t->sessionID);
533             return -1;
534         }
535     }
536     else if(p->msg.arg0 == ENCR_SET_OFF){ // 암호화 모드 off 요청 메시지
537         if(t->encryption == ENCR_ON && security_deinit(t->sessionID) == 1){ // 현재 암호화 모드가 on 상태인 경우
538             enc_p = get_apacket();
539             t->encryption = ENCR_OFF; // 현재 연결에 대한 암호화 모드 off
540             enc_p->msg.command = A_ENCR;
541             enc_p->msg.arg0 = ENCR_SET_OFF;
542             enc_p->msg.arg1 = p->msg.arg1;
543             send_packet(enc_p, t);
544         }
545         else { // 암호화 모드 off에 실패한 경우
546             E("security_deinit error\n");
547             send_encr_fail(p, t, ENCR_OFF_FAIL); // 암호화 모드 off 실패 메시지 전송
548             return -1;
549         }
550     }
551     else if(p->msg.arg0 == ENCR_GET){ // 암호화 모드의 상태 요청 메시지인 경우
552         enc_p = get_apacket();
553         enc_p->msg.command = A_ENCR;
554         enc_p->msg.arg0 = ENCR_GET; // 암호화 모드 status get메시지
555         enc_p->msg.arg1 = p->msg.arg1;
556         if(t->encryption == ENCR_ON){ // 암호화 모드가 on인 경우
557             enc_p->msg.data_length = 13;
558             strncpy((char*)enc_p->data, "encryption:on", enc_p->msg.data_length); // encryption:on 메시지 전송
559         } else if(t->encryption == ENCR_OFF){ // 암호화 모드가 off인 경우
560             enc_p->msg.data_length = 14;
561             strncpy((char*)enc_p->data, "encryption:off", enc_p->msg.data_length); // encryption:off 메시지 전송
562         }
563         send_packet(enc_p, t);
564     }
565     else if (p->msg.arg0 == ENCR_ON_FAIL) // 암호화 모드를 on 하는 도중 실패한 경우 받는 메시지
566     {
567         t->encryption = ENCR_OFF; // 암호화 모드를 다시 off
568         E("encryption on failed\n");
569     }
570     else if (p->msg.arg0 == ENCR_OFF_FAIL) // 암호화 모드를 off하는 도중 실패한 경우 받는 메시지
571     {
572         //t->encryption = ENCR_ON;
573         E("encryption off failed\n");
574     }
575     //put_apacket(enc_p);
576     return 0;
577
578 }
579 #endif
580
581
582 static void send_ready(unsigned local, unsigned remote, atransport *t)
583 {
584     I("Calling send_ready \n");
585     apacket *p = get_apacket();
586     p->msg.command = A_OKAY;
587     p->msg.arg0 = local;
588     p->msg.arg1 = remote;
589     send_packet(p, t);
590 }
591
592 static void send_close(unsigned local, unsigned remote, atransport *t)
593 {
594     I("Calling send_close \n");
595     apacket *p = get_apacket();
596     p->msg.command = A_CLSE;
597     p->msg.arg0 = local;
598     p->msg.arg1 = remote;
599     send_packet(p, t);
600 }
601
602 static void send_connect(atransport *t)
603 {
604     I("Calling send_connect \n");
605     apacket *cp = get_apacket();
606     cp->msg.command = A_CNXN;
607     cp->msg.arg0 = A_VERSION;
608 #ifdef SUPPORT_ENCRYPT
609    cp->msg.arg1 = MAX_PAYLOAD - 100; // connection 시, sdb server의 패킷 크기를 암호화 오버로드 만큼 줄임
610 #else
611     cp->msg.arg1 = MAX_PAYLOAD;
612 #endif
613     char device_name[256]={0,};
614     int r = 0;
615     int status = 0;
616     if (request_lock_state_to_plugin(LOCKTYPE_PASSWORD) == 1) {
617         status = 1;
618         t->connection_state = CS_PWLOCK;
619     }
620
621     if (is_emulator()) {
622         r = get_emulator_name(device_name, sizeof device_name);
623     } else {
624         r = get_device_name(device_name, sizeof device_name);
625     }
626     if (r < 0) {
627         snprintf((char*) cp->data, sizeof cp->data, "%s::%s::%d", sdb_device_banner, DEFAULT_DEVICENAME, status);
628     } else {
629         snprintf((char*) cp->data, sizeof cp->data, "%s::%s::%d", sdb_device_banner, device_name, status);
630     }
631
632     if (extcmd != NULL) {
633         char extbuf[BUF_SIZE] = {0,};
634         snprintf(extbuf, sizeof extbuf, "::%s", extcmd);
635         strncat((char*) cp->data, extbuf, sizeof(cp->data) - strlen(cp->data)- 1);
636     }
637     cp->msg.data_length = strlen((char*) cp->data) + 1;
638     D("CNXN data: %s\n", (char*)cp->data);
639
640     send_packet(cp, t);
641 }
642
643 void send_device_status()
644 {
645     I("broadcast device status\n");
646     apacket* cp = get_apacket();
647     cp->msg.command = A_STAT;
648     cp->msg.arg0 = is_pwlocked;
649     cp->msg.arg1 = 0;
650
651     broadcast_transport(cp);
652
653     //all broadcasted packets are memory copied
654     //so, we should call put_apacket
655     put_apacket(cp);
656 }
657
658 static char *connection_state_name(atransport *t)
659 {
660     if (t == NULL) {
661         return "unknown";
662     }
663
664     switch(t->connection_state) {
665     case CS_BOOTLOADER:
666         return "bootloader";
667     case CS_DEVICE:
668         return "device";
669     case CS_OFFLINE:
670         return "offline";
671     default:
672         return "unknown";
673     }
674 }
675
676 static int get_str_cmdline(char *src, char *dest, char str[], int str_size) {
677     char *s = strstr(src, dest);
678     if (s == NULL) {
679         return -1;
680     }
681     char *e = strstr(s, " ");
682     if (e == NULL) {
683         return -1;
684     }
685
686     int len = e-s-strlen(dest);
687
688     if (len >= str_size) {
689         E("buffer size(%d) should be bigger than %d\n", str_size, len+1);
690         return -1;
691     }
692
693     strncpy(str, s + strlen(dest), len);
694     str[len]='\0';
695     return len;
696 }
697
698 int get_emulator_forward_port() {
699     SdbdCommandlineArgs *sdbd_args = &sdbd_commandline_args; /* alias */
700
701     if (sdbd_args->emulator.host == NULL) {
702         return -1;
703     }
704
705     return sdbd_args->emulator.port;
706 }
707
708 int get_emulator_name(char str[], int str_size) {
709     SdbdCommandlineArgs *sdbd_args = &sdbd_commandline_args; /* alias */
710
711     if (sdbd_args->emulator.host == NULL) {
712         return -1;
713     }
714
715     s_strncpy(str, sdbd_args->emulator.host, str_size);
716     return 0;
717 }
718
719 int get_device_name(char str[], int str_size) {
720     char *value = NULL;
721     int r = system_info_get_platform_string("http://tizen.org/system/model_name", &value);
722     if (r != SYSTEM_INFO_ERROR_NONE) {
723         E("fail to get system model:%d\n", errno);
724         return -1;
725     } else {
726         s_strncpy(str, value, str_size);
727         D("returns model_name:%s\n", value);
728         if (value != NULL) {
729             free(value);
730         }
731         return 0;
732     }
733     /*
734     int fd = unix_open(USB_SERIAL_PATH, O_RDONLY);
735     if (fd < 0) {
736         D("fail to read:%s (%d)\n", USB_SERIAL_PATH, errno);
737         return -1;
738     }
739
740     if(read_line(fd, str, str_size)) {
741         D("device serial name: %s\n", str);
742         sdb_close(fd);
743         return 0;
744     }
745     sdb_close(fd);
746     */
747     return -1;
748 }
749
750 static int get_cmdline_value(char *split, char str[], int str_size) {
751     char cmdline[512];
752     int fd = unix_open(PROC_CMDLINE_PATH, O_RDONLY);
753
754     if (fd < 0) {
755         E("fail to read /proc/cmdline\n");
756         return -1;
757     }
758     if(read_line(fd, cmdline, sizeof(cmdline))) {
759         D("qemu cmd: %s\n", cmdline);
760         if (get_str_cmdline(cmdline, split, str, str_size) < 1) {
761             E("could not get the (%s) value from cmdline\n", split);
762             sdb_close(fd);
763             return -1;
764         }
765     }
766     sdb_close(fd);
767     return 0;
768 }
769
770 int get_emulator_hostip(char str[], int str_size) {
771     return get_cmdline_value("host_ip=", str, str_size);
772 }
773
774 int get_emulator_guestip(char str[], int str_size) {
775     int           s;
776     struct ifreq ifr;
777     struct sockaddr_in *sin;
778
779     s = socket(AF_INET, SOCK_DGRAM, 0);
780     if(s < 0) {
781         E("socket error\n");
782         return -1;
783     }
784
785     snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "%s", GUEST_IP_INTERFACE);
786     if(ioctl(s, SIOCGIFHWADDR, &ifr) < 0) {
787         E("ioctl hwaddr error\n");
788         sdb_close(s);
789         return -1;
790     }
791
792     if(ioctl(s, SIOCGIFADDR, &ifr) < 0) {
793         E("ioctl addr error\n");
794         sdb_close(s);
795         return -1;
796     }
797     sin = (struct sockaddr_in *)&ifr.ifr_addr;
798     snprintf(str, str_size, "%s", inet_ntoa(sin->sin_addr));
799     sdb_close(s);
800
801     return 0;
802 }
803
804 void parse_banner(char *banner, atransport *t)
805 {
806     char *type, *product, *end;
807
808     D("parse_banner: %s\n", banner);
809     type = banner;
810     product = strchr(type, ':');
811     if(product) {
812         *product++ = 0;
813     } else {
814         product = "";
815     }
816
817         /* remove trailing ':' */
818     end = strchr(product, ':');
819     if(end) *end = 0;
820
821         /* save product name in device structure */
822     if (t->product == NULL) {
823         t->product = strdup(product);
824     } else if (strcmp(product, t->product) != 0) {
825         free(t->product);
826         t->product = strdup(product);
827     }
828
829     if(!strcmp(type, "bootloader")){
830         I("setting connection_state to CS_BOOTLOADER\n");
831         t->connection_state = CS_BOOTLOADER;
832         update_transports();
833         return;
834     }
835
836     if(!strcmp(type, "device")) {
837         I("setting connection_state to CS_DEVICE\n");
838         t->connection_state = CS_DEVICE;
839         update_transports();
840         return;
841     }
842
843     if(!strcmp(type, "recovery")) {
844         I("setting connection_state to CS_RECOVERY\n");
845         t->connection_state = CS_RECOVERY;
846         update_transports();
847         return;
848     }
849
850     if(!strcmp(type, "sideload")) {
851         I("setting connection_state to CS_SIDELOAD\n");
852         t->connection_state = CS_SIDELOAD;
853         update_transports();
854         return;
855     }
856
857     t->connection_state = CS_HOST;
858 }
859
860 static void update_version(atransport *t, int version, size_t payload)
861 {
862 #ifdef SUPPORT_ENCRYPT
863     size_t max_payload = MAX_PAYLOAD - 100;
864 #else
865     size_t max_payload = MAX_PAYLOAD;
866 #endif
867     t->protocol_version = min(version, A_VERSION);
868     t->max_payload = min(payload, max_payload);
869     D("update transport version. version=%x, max_payload=%zu\n", t->protocol_version, t->max_payload);
870 }
871
872 void handle_packet(apacket *p, atransport *t)
873 {
874     // Verify pointer p
875     int result = access((const char *) p, F_OK);
876     if ((result == -1) && (errno == EFAULT)) {
877         fatal("Invalid apacket = [0x%p]", p);
878     }
879
880     asocket *s;
881
882 //    D("handle_packet() %c%c%c%c\n", ((char*) (&(p->msg.command)))[0],
883 //                ((char*) (&(p->msg.command)))[1],
884 //                ((char*) (&(p->msg.command)))[2],
885 //                ((char*) (&(p->msg.command)))[3]);
886
887     print_packet("recv", p);
888
889     switch(p->msg.command){
890     case A_SYNC:
891         if(p->msg.arg0){
892             send_packet(p, t);
893             if(HOST) send_connect(t);
894         } else {
895             t->connection_state = CS_OFFLINE;
896             handle_offline(t);
897             send_packet(p, t);
898         }
899         return;
900
901     case A_CNXN: /* CONNECT(version, maxdata, "system-id-string") */
902             /* XXX verify version, etc */
903         if(t->connection_state != CS_OFFLINE) {
904             t->connection_state = CS_OFFLINE;
905             handle_offline(t);
906         }
907         update_version(t, p->msg.arg0, p->msg.arg1);
908         parse_banner((char*) p->data, t);
909         handle_online();
910         if(!HOST) send_connect(t);
911         break;
912
913     case A_OPEN: /* OPEN(local-id, 0, "destination") */
914         if (request_lock_state_to_plugin(LOCKTYPE_PASSWORD) == 1 && t->connection_state == CS_PWLOCK) {
915             // in case of already locked before get A_CNXN
916             E("open failed due to password locked before get A_CNXN:%d\n", t->connection_state);
917             send_close(0, p->msg.arg0, t);
918         } else {
919             if(t->connection_state != CS_OFFLINE) {
920                 char *name = (char*) p->data;
921                 name[p->msg.data_length > 0 ? p->msg.data_length - 1 : 0] = 0;
922                 s = create_local_service_socket(name);
923                 if(s == 0) {
924                     send_close(0, p->msg.arg0, t);
925                 } else {
926                     s->peer = create_remote_socket(p->msg.arg0, t);
927                     s->peer->peer = s;
928                     send_ready(s->id, s->peer->id, t);
929                     s->ready(s);
930                 }
931             }
932         }
933         break;
934
935     case A_OKAY: /* READY(local-id, remote-id, "") */
936         if(t->connection_state != CS_OFFLINE) {
937             if((s = find_local_socket(p->msg.arg1))) {
938                 if(s->peer == 0) {
939                     s->peer = create_remote_socket(p->msg.arg0, t);
940                     s->peer->peer = s;
941                 }
942                 s->ready(s);
943             }
944         }
945         break;
946
947     case A_CLSE: /* CLOSE(local-id, remote-id, "") */
948         if(t->connection_state != CS_OFFLINE) {
949             if((s = find_local_socket(p->msg.arg1))) {
950                 s->close(s);
951             }
952         }
953         break;
954
955     case A_WRTE:
956         if(t->connection_state != CS_OFFLINE) {
957             if((s = find_local_socket(p->msg.arg1))) {
958                 unsigned rid = p->msg.arg0;
959                 p->len = p->msg.data_length;
960
961                 if(s->enqueue(s, p) == 0) {
962                     I("Enqueue the socket\n");
963                     send_ready(s->id, rid, t);
964                 }
965                 return;
966             }
967         }
968         break;
969 #ifdef SUPPORT_ENCRYPT
970     case A_ENCR: // 암호화 메시지인 경우
971         if(t->connection_state != CS_OFFLINE) {
972             handle_encr_packet(p, t);
973         }
974         break;
975 #endif
976
977     default:
978         printf("handle_packet: what is %08x?!\n", p->msg.command);
979     }
980
981     put_apacket(p);
982 }
983
984 alistener listener_list = {
985     .next = &listener_list,
986     .prev = &listener_list,
987 };
988
989 static void ss_listener_event_func(int _fd, unsigned ev, void *_l)
990 {
991     asocket *s;
992     int ret = -1;
993
994     if(ev & FDE_READ) {
995         struct sockaddr addr;
996         socklen_t alen;
997         int fd;
998
999         alen = sizeof(addr);
1000         fd = sdb_socket_accept(_fd, &addr, &alen);
1001         if(fd < 0) return;
1002
1003         ret = sdb_socket_setbufsize(fd, CHUNK_SIZE);
1004         if (ret == -1) {
1005             D("sdbd: sdb_socket_setbufsize failed (%d)\n", ret);
1006         }
1007
1008         s = create_local_socket(fd);
1009         if(s) {
1010             connect_to_smartsocket(s);
1011             return;
1012         }
1013
1014         sdb_close(fd);
1015     }
1016 }
1017
1018 static void listener_event_func(int _fd, unsigned ev, void *_l)
1019 {
1020     alistener *l = _l;
1021     asocket *s;
1022
1023     if(ev & FDE_READ) {
1024         struct sockaddr addr;
1025         socklen_t alen;
1026         int fd;
1027
1028         alen = sizeof(addr);
1029         fd = sdb_socket_accept(_fd, &addr, &alen);
1030         if(fd < 0) return;
1031
1032         s = create_local_socket(fd);
1033         if(s) {
1034             s->transport = l->transport;
1035             connect_to_remote(s, l->connect_to);
1036             return;
1037         }
1038
1039         sdb_close(fd);
1040     }
1041 }
1042
1043 static void  free_listener(alistener*  l)
1044 {
1045     if (l->next) {
1046         l->next->prev = l->prev;
1047         l->prev->next = l->next;
1048         l->next = l->prev = l;
1049     }
1050
1051     // closes the corresponding fd
1052     fdevent_remove(&l->fde);
1053
1054     if (l->local_name)
1055         free((char*)l->local_name);
1056
1057     if (l->connect_to)
1058         free((char*)l->connect_to);
1059
1060     if (l->transport) {
1061         remove_transport_disconnect(l->transport, &l->disconnect);
1062     }
1063     free(l);
1064 }
1065
1066 static void listener_disconnect(void*  _l, atransport*  t)
1067 {
1068     alistener*  l = _l;
1069
1070     free_listener(l);
1071 }
1072
1073 int local_name_to_fd(const char *name)
1074 {
1075     int port;
1076
1077     if(!strncmp("tcp:", name, 4)){
1078         int  ret;
1079         port = atoi(name + 4);
1080         ret = socket_loopback_server(port, SOCK_STREAM);
1081         return ret;
1082     }
1083 #ifndef HAVE_WIN32_IPC  /* no Unix-domain sockets on Win32 */
1084     // It's non-sensical to support the "reserved" space on the sdb host side
1085     if(!strncmp(name, "local:", 6)) {
1086         return socket_local_server(name + 6,
1087                 ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_STREAM);
1088     } else if(!strncmp(name, "localabstract:", 14)) {
1089         return socket_local_server(name + 14,
1090                 ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_STREAM);
1091     } else if(!strncmp(name, "localfilesystem:", 16)) {
1092         return socket_local_server(name + 16,
1093                 ANDROID_SOCKET_NAMESPACE_FILESYSTEM, SOCK_STREAM);
1094     }
1095
1096 #endif
1097     printf("unknown local portname '%s'\n", name);
1098     return -1;
1099 }
1100
1101 static int remove_listener(const char *local_name, const char *connect_to, atransport* transport)
1102 {
1103     alistener *l;
1104
1105     for (l = listener_list.next; l != &listener_list; l = l->next) {
1106         if (!strcmp(local_name, l->local_name) &&
1107             !strcmp(connect_to, l->connect_to) &&
1108             l->transport && l->transport == transport) {
1109
1110             listener_disconnect(l, transport);
1111             return 0;
1112         }
1113     }
1114
1115     return -1;
1116 }
1117
1118 static int install_listener(const char *local_name, const char *connect_to, atransport* transport)
1119 {
1120     alistener *l;
1121
1122     //printf("install_listener('%s','%s')\n", local_name, connect_to);
1123
1124     for(l = listener_list.next; l != &listener_list; l = l->next){
1125         if(strcmp(local_name, l->local_name) == 0) {
1126             char *cto;
1127
1128                 /* can't repurpose a smartsocket */
1129             if(l->connect_to[0] == '*') {
1130                 return -1;
1131             }
1132
1133             cto = strdup(connect_to);
1134             if(cto == 0) {
1135                 return -1;
1136             }
1137
1138             //printf("rebinding '%s' to '%s'\n", local_name, connect_to);
1139             free((void*) l->connect_to);
1140             l->connect_to = cto;
1141             if (l->transport != transport) {
1142                 remove_transport_disconnect(l->transport, &l->disconnect);
1143                 l->transport = transport;
1144                 add_transport_disconnect(l->transport, &l->disconnect);
1145             }
1146             return 0;
1147         }
1148     }
1149
1150     if((l = calloc(1, sizeof(alistener))) == 0) goto nomem;
1151     if((l->local_name = strdup(local_name)) == 0) goto nomem;
1152     if((l->connect_to = strdup(connect_to)) == 0) goto nomem;
1153
1154
1155     l->fd = local_name_to_fd(local_name);
1156     if(l->fd < 0) {
1157         free((void*) l->local_name);
1158         free((void*) l->connect_to);
1159         free(l);
1160         printf("cannot bind '%s'\n", local_name);
1161         return -2;
1162     }
1163
1164     if (close_on_exec(l->fd) < 0) {
1165         E("fail to close fd exec:%d\n",l->fd);
1166     }
1167     if(!strcmp(l->connect_to, "*smartsocket*")) {
1168         fdevent_install(&l->fde, l->fd, ss_listener_event_func, l);
1169     } else {
1170         fdevent_install(&l->fde, l->fd, listener_event_func, l);
1171     }
1172     fdevent_set(&l->fde, FDE_READ);
1173
1174     l->next = &listener_list;
1175     l->prev = listener_list.prev;
1176     l->next->prev = l;
1177     l->prev->next = l;
1178     l->transport = transport;
1179
1180     if (transport) {
1181         l->disconnect.opaque = l;
1182         l->disconnect.func   = listener_disconnect;
1183         add_transport_disconnect(transport, &l->disconnect);
1184     }
1185     return 0;
1186
1187 nomem:
1188     fatal("cannot allocate listener");
1189     return 0;
1190 }
1191
1192 static void sdb_cleanup(void)
1193 {
1194     clear_sdbd_commandline_args(&sdbd_commandline_args);
1195
1196     if (is_support_usbproto()) {
1197         usb_cleanup();
1198     }
1199 //    if(required_pid > 0) {
1200 //        kill(required_pid, SIGKILL);
1201 //    }
1202
1203     unload_sdbd_plugin();
1204 }
1205
1206 void start_device_log(void)
1207 {
1208     int fd;
1209     char    path[PATH_MAX] = {0, };
1210     char    path_folder[PATH_MAX] = {0, };
1211     char    path_file[PATH_MAX] = {0, };
1212     struct tm now;
1213     time_t t;
1214
1215     // read the trace mask from persistent property persist.sdb.trace_mask
1216     // give up if the property is not set or cannot be parsed
1217     char* p_trace = get_sdb_log_conf("SDB_TRACE");
1218     if ((p_trace == NULL ) && !is_enable_sdbd_log()) {
1219         return;
1220     } else {
1221         free(p_trace);
1222     }
1223     char* p_path = get_sdb_log_conf("SDBD_LOG_PATH");
1224     if (p_path) {
1225         snprintf(path_folder, sizeof(path_folder), "%s", p_path);
1226         free(p_path);
1227     } else if (g_capabilities.log_path[0] != '\0') {
1228         snprintf(path_folder, sizeof(path_folder), "%s", g_capabilities.log_path);
1229     } else {
1230         return;
1231     }
1232
1233     tzset();
1234     time(&t);
1235     localtime_r(&t, &now);
1236
1237     strftime(path_file, sizeof(path_file),
1238                     "sdbd-%Y-%m-%d-%H-%M-%S.txt",
1239                     &now);
1240
1241     snprintf(path, sizeof(path), "%s/%s", path_folder, path_file);
1242
1243     fd = unix_open(path, O_WRONLY | O_CREAT | O_TRUNC, 0644);
1244     if (fd < 0) {
1245         return;
1246     }
1247
1248     // redirect stdout and stderr to the log file
1249     dup2(fd, 1);
1250     dup2(fd, 2);
1251     fprintf(stderr,"--- sdbd starting (pid %d) ---\n", getpid());
1252     sdb_close(fd);
1253
1254     fd = unix_open("/dev/null", O_RDONLY);
1255     if (fd < 0) {
1256         // hopefully not gonna happen
1257         return;
1258     }
1259     dup2(fd, 0);
1260     sdb_close(fd);
1261 }
1262
1263 /* Constructs a local name of form tcp:port.
1264  * target_str points to the target string, it's content will be overwritten.
1265  * target_size is the capacity of the target string.
1266  * server_port is the port number to use for the local name.
1267  */
1268 void build_local_name(char* target_str, size_t target_size, int server_port)
1269 {
1270   snprintf(target_str, target_size, "tcp:%d", server_port);
1271 }
1272
1273 static void init_drop_privileges() {
1274 #ifdef _DROP_PRIVILEGE
1275     rootshell_mode = 0;
1276 #else
1277     rootshell_mode = 1;
1278 #endif
1279 }
1280
1281 int should_drop_privileges() {
1282     if (rootshell_mode == 1) { // if root, then don't drop
1283         return 0;
1284     }
1285     return 1;
1286 }
1287
1288 #include <gio/gio.h>
1289
1290 #define DEVICED_BUS            "org.tizen.system.deviced"
1291 #define DEVICED_CORE_PATH      "/Org/Tizen/System/DeviceD/Core"
1292 #define BOOTING_DONE_SIGNAL    "BootingDone"
1293 #define DEVICED_CORE_INTERFACE "org.tizen.system.deviced.core"
1294 #define SDBD_BOOT_INFO_FILE    "/tmp/sdbd_boot_info"
1295
1296 static GMainLoop *g_mainloop;
1297
1298 static void booting_done_signal_subscriber(GDBusConnection *connection,
1299     const gchar *sender, const gchar *path, const gchar *interface,
1300     const gchar *signal, GVariant *parameters, gpointer user_data)
1301 {
1302     if (g_strcmp0(signal, BOOTING_DONE_SIGNAL) != 0) {
1303         D("received signal(%s) does not match the desired signal(%s)\n",
1304           signal, BOOTING_DONE_SIGNAL);
1305         return;
1306     }
1307
1308     D("received the \"%s\" signal\n", signal);
1309
1310     char cRealPath[PATH_MAX]= {0, };
1311     booting_done = 1;
1312     if (access(SDBD_BOOT_INFO_FILE, F_OK) == 0) {
1313         I("booting is already done\n");
1314     } else {
1315         FILE *info_file = fopen(SDBD_BOOT_INFO_FILE, "w");
1316         if (info_file != NULL) {
1317                 if (realpath(SDBD_BOOT_INFO_FILE, cRealPath) != NULL) {
1318                          if (strcmp(SDBD_BOOT_INFO_FILE, cRealPath) == 0) {
1319                                  fprintf(info_file, "%d", 1);
1320                                  I("booting is done\n");
1321                          } else {
1322                                  D("Path has symbolic link, security risk \n");
1323                                  return;
1324                          }
1325                 } else {
1326                         D("Getting realpath failed\n");
1327                 }
1328                 fclose(info_file);
1329         }
1330     }
1331
1332     I("handled the booting done signal\n");
1333     g_main_loop_quit(g_mainloop);
1334 }
1335
1336 static void *bootdone_cb(void *args)
1337 {
1338     GError *error = NULL;
1339     GDBusConnection *connection = NULL;
1340     guint id;
1341
1342     connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
1343     if (connection == NULL) {
1344         if (error != NULL) {
1345             E("failed to connect to the system bus: %s\n", error->message);
1346             g_error_free(error);
1347         } else {
1348             E("failed to connect to the system bus\n");
1349         }
1350         return NULL;
1351     }
1352
1353     g_mainloop = g_main_loop_new(NULL, false);
1354     if (g_mainloop == NULL) {
1355         E("failed to create a g_main_loop\n");
1356         goto bootdone_out;
1357     }
1358
1359     id = g_dbus_connection_signal_subscribe(connection,
1360         DEVICED_BUS, DEVICED_CORE_INTERFACE, BOOTING_DONE_SIGNAL,
1361         DEVICED_CORE_PATH, NULL, G_DBUS_SIGNAL_FLAGS_NONE,
1362         booting_done_signal_subscriber, NULL, NULL);
1363     if (id == 0) {
1364         E("failed to subscribe to the booting done signal\n");
1365         goto bootdone_out;
1366     }
1367
1368     I("wait for the booting done signal\n");
1369     g_main_loop_run(g_mainloop);
1370
1371     g_dbus_connection_signal_unsubscribe(connection, id);
1372
1373 bootdone_out:
1374     if (g_mainloop != NULL) {
1375         g_main_loop_unref(g_mainloop);
1376     }
1377     if (connection != NULL) {
1378         g_object_unref(connection);
1379     }
1380     I("exit the bootdone_cb thread\n");
1381
1382     return NULL;
1383 }
1384
1385 void register_bootdone_cb()
1386 {
1387     sdb_thread_t t;
1388     if (sdb_thread_create(&t, bootdone_cb, NULL)) {
1389         E("can not create a service thread to check the booting done\n");
1390         return;
1391     }
1392     I("created the bootdone_cb thread\n");
1393 }
1394
1395 static int sdbd_set_groups(const char *name, int gid, struct group_info default_groups[], int default_groups_size) {
1396     gid_t *group_ids = NULL;
1397     int ngroups = 0;
1398     int i, j = 0;
1399     int group_match = 0;
1400     int added_group_cnt = 0;
1401
1402     if (getgrouplist(name, gid, NULL, &ngroups) == -1) {
1403         D("group list : ngroups = %d\n", ngroups);
1404     }
1405     group_ids = malloc((ngroups + default_groups_size) * sizeof(gid_t));
1406     if (group_ids == NULL) {
1407         E("failed to allocate group_ids(%zu)\n", (ngroups + default_groups_size) * sizeof(gid_t));
1408         return -1;
1409     }
1410     if (getgrouplist(name, gid, group_ids, &ngroups) == -1) {
1411         E("failed to getgrouplist(), ngroups = %d\n", ngroups);
1412         free(group_ids);
1413         return -1;
1414     }
1415     if(default_groups_size >= 1) {
1416         for (i = 0; default_groups[i].name != NULL; i++) {
1417             for (j = 0; j < ngroups; j++) {
1418                 if (group_ids[j] == default_groups[i].gid) {
1419                     group_match = 1;
1420                     break;
1421                 }
1422             }
1423             if (group_match == 0 && default_groups[i].gid != -1) {
1424                 group_ids[ngroups + added_group_cnt] = default_groups[i].gid;
1425                 added_group_cnt ++;
1426             }
1427             group_match = 0;
1428         }
1429     }
1430     if (setgroups(ngroups+added_group_cnt, group_ids) != 0) {
1431         E("failed to setgroups().\n");
1432         free(group_ids);
1433         return -1;
1434     }
1435
1436     free(group_ids);
1437     return 0;
1438 }
1439
1440 static int sdbd_get_user_pwd(const char* user_name, struct passwd* pwd, char* buf, size_t bufsize) {
1441     struct passwd *result = NULL;
1442     int ret = 0;
1443
1444     ret = getpwnam_r(user_name, pwd, buf, bufsize, &result);
1445     if (result == NULL) {
1446         if (ret == 0) {
1447             E("Not found passwd : username(%s)\n", user_name);
1448         } else {
1449             errno = ret;
1450             E("failed to getpwnam_r\n");
1451         }
1452         return -1;
1453     }
1454
1455     return 0;
1456 }
1457
1458 static int sdbd_get_group(const char* group_name, struct group* grp, char* buf, size_t bufsize) {
1459     struct group *result = NULL;
1460     int ret = 0;
1461
1462     ret = getgrnam_r(group_name, grp, buf, bufsize, &result);
1463     if (result == NULL) {
1464         if (ret == 0) {
1465             E("Not found group : groupname(%s)\n", group_name);
1466         } else {
1467             errno = ret;
1468             E("failed to getgrnam_r\n");
1469         }
1470         return -1;
1471     }
1472
1473     return 0;
1474 }
1475
1476 int set_sdk_user_privileges(int is_drop_capability_after_fork) {
1477     if (!is_init_sdk_userinfo) {
1478         E("failed to init sdk user information.\n");
1479         return -1;
1480     }
1481
1482     /*
1483     * If a process switches its real, effective, or saved uids from at least one being 0 to all being non-zero,
1484     * then both the permitted and effective capabilities are cleared.
1485     */
1486     if(is_drop_capability_after_fork) {
1487
1488         if (setuid(g_root_user_id) != 0) {
1489             E("set root user id failed (errno: %d)\n", errno);
1490             return -1;
1491         }
1492     }
1493
1494     if (sdbd_set_groups(SDK_USER_NAME, g_sdk_group_id, g_default_groups, SDB_DEFAULT_GROUPS_CNT) < 0) {
1495         E("set groups failed (errno: %d)\n", errno);
1496         return -1;
1497     }
1498
1499     if (setgid(g_sdk_group_id) != 0) {
1500         E("set group id failed (errno: %d)\n", errno);
1501         return -1;
1502     }
1503
1504     if (setuid(g_sdk_user_id) != 0) {
1505         E("set user id failed (errno: %d)\n", errno);
1506         return -1;
1507 //        if(is_drop_capability_after_fork) {
1508 //            return -1;
1509 //        }
1510     }
1511
1512     if (chdir(g_sdk_home_dir) < 0) {
1513         E("unable to change working directory to %s\n", g_sdk_home_dir);
1514     }
1515
1516     // TODO: use pam later
1517     if (g_sdk_home_dir_env) {
1518         putenv(g_sdk_home_dir_env);
1519     }
1520
1521     return 0;
1522 }
1523
1524 int set_root_privileges() {
1525
1526     if (sdbd_set_groups(ROOT_USER_NAME, g_root_group_id, NULL, 0) < 0) {
1527         E("set root groups failed (errno: %d)\n", errno);
1528     }
1529
1530     if (setgid(g_root_group_id) != 0) {
1531         E("set root group id failed (errno: %d)\n", errno);
1532     }
1533
1534     if (setuid(g_root_user_id) != 0) {
1535         E("set root user id failed (errno: %d)\n", errno);
1536     }
1537
1538     if (chdir(g_root_home_dir) < 0) {
1539         E("unable to change root working directory to %s\n", g_sdk_home_dir);
1540     }
1541
1542     // TODO: use pam later
1543     if (g_root_home_dir_env) {
1544         putenv(g_root_home_dir_env);
1545     }
1546
1547     return 0;
1548 }
1549
1550 #define SDB_PW_GR_DEFAULT_SIZE  (16*1024)
1551 static long get_passwd_bufsize() {
1552     long bufsize = 0;
1553
1554     bufsize = sysconf(_SC_GETPW_R_SIZE_MAX);
1555     if(bufsize < 0) {
1556         bufsize = SDB_PW_GR_DEFAULT_SIZE;
1557     }
1558
1559     return bufsize;
1560 }
1561
1562 static long get_group_bufsize() {
1563     long bufsize = 0;
1564
1565     bufsize = sysconf(_SC_GETGR_R_SIZE_MAX);
1566     if(bufsize < 0) {
1567         bufsize = SDB_PW_GR_DEFAULT_SIZE;
1568     }
1569
1570     return bufsize;
1571 }
1572
1573 static int init_sdb_default_groups() {
1574     struct group grp;
1575     char *buf = NULL;
1576     long bufsize = 0;
1577     int i = 0;
1578
1579     bufsize = get_group_bufsize();
1580     buf = malloc(bufsize);
1581     if (buf == NULL) {
1582         E("failed to allocate gruop buf(%ld)\n", bufsize);
1583         return -1;
1584     }
1585
1586     for (i = 0; g_default_groups[i].name != NULL; i++) {
1587         memset(buf, 0, bufsize);
1588         if (sdbd_get_group(g_default_groups[i].name, &grp, buf, bufsize) == 0) {
1589             g_default_groups[i].gid = grp.gr_gid;
1590         } else {
1591             E("failed get group info.(errno: %d)\n", errno);
1592         }
1593     }
1594
1595     free(buf);
1596     return 0;
1597 }
1598
1599 static void set_static_root_userinfo() {
1600     g_root_user_id = STATIC_ROOT_USER_ID;
1601     g_root_group_id = STATIC_ROOT_GROUP_ID;
1602     g_root_home_dir = STATIC_ROOT_HOME_DIR;
1603 }
1604
1605 static void set_static_sdk_userinfo() {
1606     g_sdk_user_id = STATIC_SDK_USER_ID;
1607     g_sdk_group_id = STATIC_SDK_GROUP_ID;
1608     g_sdk_home_dir = STATIC_SDK_HOME_DIR;
1609 }
1610
1611 static int init_root_userinfo() {
1612     struct passwd pwd;
1613     char *buf = NULL;
1614     long bufsize = 0;
1615
1616     bufsize = get_passwd_bufsize();
1617     buf = malloc(bufsize);
1618     if (buf == NULL) {
1619         E("failed to allocate passwd buf(%ld)\n", bufsize);
1620         set_static_root_userinfo();
1621     } else {
1622         if (sdbd_get_user_pwd(ROOT_USER_NAME, &pwd, buf, bufsize) < 0) {
1623             E("failed to get root user passwd info.(errno: %d)\n", errno);
1624             set_static_root_userinfo();
1625         } else {
1626             D("username=%s, uid=%d, gid=%d, dir=%s\n", pwd.pw_name, pwd.pw_uid, pwd.pw_gid, pwd.pw_dir);
1627
1628             g_root_user_id = pwd.pw_uid;
1629             g_root_group_id = pwd.pw_gid;
1630             g_root_home_dir = strdup(pwd.pw_dir);
1631         }
1632         free(buf);
1633     }
1634
1635     int env_size = strlen("HOME=") + strlen(g_root_home_dir) + 1;
1636     g_root_home_dir_env = malloc(env_size);
1637     if(g_root_home_dir_env == NULL) {
1638         E("failed to allocate for home dir env string\n");
1639     } else {
1640         snprintf(g_root_home_dir_env, env_size, "HOME=%s", g_root_home_dir);
1641     }
1642
1643     return 0;
1644 }
1645
1646 static int init_sdk_userinfo() {
1647     struct passwd pwd;
1648     char *buf = NULL;
1649     long bufsize = 0;
1650
1651     if (is_init_sdk_userinfo) {
1652         return 0;
1653     }
1654
1655     if (init_sdb_default_groups() < 0) {
1656         E("failed to initialize default groups.\n");
1657     }
1658
1659     bufsize = get_passwd_bufsize();
1660     buf = malloc(bufsize);
1661     if (buf == NULL) {
1662         E("failed to allocate passwd buf(%ld)\n", bufsize);
1663         set_static_sdk_userinfo();
1664     } else {
1665         if (sdbd_get_user_pwd(SDK_USER_NAME, &pwd, buf, bufsize) < 0) {
1666             E("get user passwd info.(errno: %d)\n", errno);
1667             set_static_sdk_userinfo();
1668         } else {
1669             D("username=%s, uid=%d, gid=%d, dir=%s\n", pwd.pw_name, pwd.pw_uid, pwd.pw_gid, pwd.pw_dir);
1670
1671             g_sdk_user_id = pwd.pw_uid;
1672             g_sdk_group_id = pwd.pw_gid;
1673             g_sdk_home_dir = strdup(pwd.pw_dir);
1674         }
1675         free(buf);
1676     }
1677
1678     int env_size = strlen("HOME=") + strlen(g_sdk_home_dir) + 1;
1679     g_sdk_home_dir_env = malloc(env_size);
1680     if(g_sdk_home_dir_env == NULL) {
1681         E("failed to allocate for home dir env string\n");
1682     } else {
1683         snprintf(g_sdk_home_dir_env, env_size, "HOME=%s", g_sdk_home_dir);
1684     }
1685
1686     is_init_sdk_userinfo = 1;
1687     return 0;
1688 }
1689
1690 static int safe_system(char *cmd, char *argv[], char *envp[]) {
1691     pid_t pid;
1692     int status;
1693
1694     pid = fork();
1695     switch (pid) {
1696         case -1:
1697             return -1;
1698         case 0:
1699             execve(cmd, argv, envp);
1700             E("- exec '%s' failed: (errno:%d) -\n", cmd, errno);
1701             exit(-1);
1702         default:
1703             for (;;) {
1704                 pid_t p = waitpid(pid, &status, 0);
1705                 if (p == pid) {
1706                     break;
1707                 }
1708             }
1709     }
1710     return 0;
1711 }
1712
1713 static void init_sdk_requirements() {
1714     struct stat st;
1715
1716     // set env variable for temporary
1717     // TODO: should use pam instead later!!
1718     putenv("TERM=linux");
1719     putenv("HOME=/root");
1720
1721     init_sdk_userinfo();
1722     init_root_userinfo();
1723
1724     if (g_sdk_home_dir != NULL && stat(g_sdk_home_dir, &st) == 0) {
1725         if (st.st_uid != g_sdk_user_id || st.st_gid != g_sdk_group_id) {
1726             char* cmd = "/usr/bin/chown";
1727             char params[128];
1728             char* envp[128];
1729             int envp_cnt = 0;
1730             int i = 0;
1731
1732             envp[envp_cnt++] = g_strdup("TERM=linux");
1733             envp[envp_cnt++] = g_strdup("DISPLAY=:0");
1734             envp[envp_cnt] = NULL;
1735
1736             snprintf(params, sizeof(params), "%s %s:%s %s -R", cmd, SDK_USER_NAME, SDK_USER_NAME, g_sdk_home_dir);
1737
1738             char* args[] = {
1739                 cmd,
1740                 params,
1741                 NULL,
1742             };
1743             if (safe_system(cmd, args, envp) < 0) {
1744                 E("failed to change ownership to sdk user to %s\n", g_sdk_home_dir);
1745             }
1746
1747             /* free environment variables */
1748             if (envp_cnt > 0) {
1749                 for (i = 0; i < envp_cnt; i++) {
1750                     if (envp[i]) {
1751                         g_free(envp[i]);
1752                     }
1753                 }
1754             }
1755         }
1756     }
1757
1758     if (is_emulator()) {
1759         register_bootdone_cb();
1760     }
1761 }
1762
1763 static void init_capabilities(void) {
1764     int ret = -1;
1765     char *value = NULL;
1766
1767     memset(&g_capabilities, 0, sizeof(g_capabilities));
1768
1769     // CPU Architecture of model
1770     ret = system_info_get_platform_string("http://tizen.org/feature/platform.core.cpu.arch", &value);
1771     if (ret != SYSTEM_INFO_ERROR_NONE) {
1772         snprintf(g_capabilities.cpu_arch, sizeof(g_capabilities.cpu_arch),
1773                     "%s", UNKNOWN);
1774         E("fail to get the CPU architecture of model:%d\n", errno);
1775     } else {
1776         snprintf(g_capabilities.cpu_arch, sizeof(g_capabilities.cpu_arch),
1777                     "%s", value);
1778         if (value != NULL) {
1779             free(value);
1780         }
1781     }
1782
1783
1784     // Secure protocol support
1785     if(!request_capability_to_plugin(CAPABILITY_SECURE, g_capabilities.secure_protocol,
1786                             sizeof(g_capabilities.secure_protocol))) {
1787         E("failed to request. (%d:%d) \n", PLUGIN_SYNC_CMD_CAPABILITY, CAPABILITY_SECURE);
1788         snprintf(g_capabilities.secure_protocol, sizeof(g_capabilities.secure_protocol),
1789                     "%s", DISABLED);
1790     }
1791
1792
1793     // Interactive shell support
1794     if(!request_capability_to_plugin(CAPABILITY_INTER_SHELL, g_capabilities.intershell_support,
1795                             sizeof(g_capabilities.intershell_support))) {
1796         E("failed to request. (%d:%d) \n", PLUGIN_SYNC_CMD_CAPABILITY, CAPABILITY_INTER_SHELL);
1797         snprintf(g_capabilities.intershell_support, sizeof(g_capabilities.intershell_support),
1798                     "%s", DISABLED);
1799     }
1800
1801
1802     // File push/pull support
1803     if(!request_capability_to_plugin(CAPABILITY_FILESYNC, g_capabilities.filesync_support,
1804                             sizeof(g_capabilities.filesync_support))) {
1805         E("failed to request. (%d:%d) \n", PLUGIN_SYNC_CMD_CAPABILITY, CAPABILITY_FILESYNC);
1806         snprintf(g_capabilities.filesync_support, sizeof(g_capabilities.filesync_support),
1807                     "%s", DISABLED);
1808     }
1809
1810
1811     // USB protocol support
1812     if(!request_capability_to_plugin(CAPABILITY_USB_PROTOCOL, g_capabilities.usbproto_support,
1813                             sizeof(g_capabilities.usbproto_support))) {
1814         E("failed to request. (%d:%d) \n", PLUGIN_SYNC_CMD_CAPABILITY, CAPABILITY_USB_PROTOCOL);
1815         snprintf(g_capabilities.usbproto_support, sizeof(g_capabilities.usbproto_support),
1816                     "%s", DISABLED);
1817     }
1818
1819
1820     // Socket protocol support
1821     if(!request_capability_to_plugin(CAPABILITY_SOCK_PROTOCOL, g_capabilities.sockproto_support,
1822                             sizeof(g_capabilities.sockproto_support))) {
1823         E("failed to request. (%d:%d) \n", PLUGIN_SYNC_CMD_CAPABILITY, CAPABILITY_SOCK_PROTOCOL);
1824         snprintf(g_capabilities.sockproto_support, sizeof(g_capabilities.sockproto_support),
1825                     "%s", DISABLED);
1826     }
1827
1828     // Sdbd root permission
1829     snprintf(g_capabilities.root_permission, sizeof(g_capabilities.root_permission),
1830                 "%s", DISABLED);
1831
1832     // Root command support
1833     if(!request_capability_to_plugin(CAPABILITY_ROOT_ONOFF, g_capabilities.rootonoff_support,
1834                             sizeof(g_capabilities.rootonoff_support))) {
1835         E("failed to request. (%d:%d) \n", PLUGIN_SYNC_CMD_CAPABILITY, CAPABILITY_ROOT_ONOFF);
1836         snprintf(g_capabilities.rootonoff_support, sizeof(g_capabilities.rootonoff_support),
1837                     "%s", DISABLED);
1838     }
1839
1840
1841     // Encryption support
1842     if(!request_capability_to_plugin(CAPABILITY_ENCRYPTION, g_capabilities.encryption_support,
1843                             sizeof(g_capabilities.encryption_support))) {
1844         E("failed to request. (%d:%d) \n", PLUGIN_SYNC_CMD_CAPABILITY, CAPABILITY_ENCRYPTION);
1845         snprintf(g_capabilities.encryption_support, sizeof(g_capabilities.encryption_support),
1846                     "%s", DISABLED);
1847     }
1848
1849
1850     // Zone support
1851     ret = is_container_enabled();
1852     snprintf(g_capabilities.zone_support, sizeof(g_capabilities.zone_support),
1853                 "%s", ret == 1 ? ENABLED : DISABLED);
1854
1855     // Multi-User support
1856     // XXX: There is no clear way to determine whether multi-user support.
1857     // Since TZ_SYS_DEFAULT_USER is set to "owner" for multi-user support,
1858     // guess whether multiuser support through that information.
1859     const char* sys_default_user = tzplatform_getenv(TZ_SYS_DEFAULT_USER);
1860     if (sys_default_user != NULL && !strcmp(sys_default_user, "owner")) {
1861         snprintf(g_capabilities.multiuser_support, sizeof(g_capabilities.multiuser_support),
1862                     "%s", ENABLED);
1863     } else {
1864         snprintf(g_capabilities.multiuser_support, sizeof(g_capabilities.multiuser_support),
1865                     "%s", DISABLED);
1866     }
1867
1868     // Window size synchronization support
1869     snprintf(g_capabilities.syncwinsz_support, sizeof(g_capabilities.syncwinsz_support),
1870                 "%s", ENABLED);
1871
1872     // SDK Tool path
1873     if (SDK_TOOL_PATH == NULL) {
1874         E("fail to get SDK tool path.\n");
1875         snprintf(g_capabilities.sdk_toolpath, sizeof(g_capabilities.sdk_toolpath),
1876                     "%s", UNKNOWN);
1877     } else {
1878         snprintf(g_capabilities.sdk_toolpath, sizeof(g_capabilities.sdk_toolpath),
1879                     "%s", SDK_TOOL_PATH);
1880     }
1881
1882     // Profile name
1883     ret = system_info_get_platform_string("http://tizen.org/feature/profile", &value);
1884     if (ret != SYSTEM_INFO_ERROR_NONE) {
1885         snprintf(g_capabilities.profile_name, sizeof(g_capabilities.profile_name),
1886                     "%s", UNKNOWN);
1887         E("fail to get profile name:%d\n", errno);
1888     } else {
1889         snprintf(g_capabilities.profile_name, sizeof(g_capabilities.profile_name),
1890                     "%s", value);
1891         if (value != NULL) {
1892             free(value);
1893         }
1894     }
1895
1896
1897     // Vendor name
1898     ret = system_info_get_platform_string("http://tizen.org/system/manufacturer", &value);
1899     if (ret != SYSTEM_INFO_ERROR_NONE) {
1900         snprintf(g_capabilities.vendor_name, sizeof(g_capabilities.vendor_name),
1901                     "%s", UNKNOWN);
1902         E("fail to get the Vendor name:%d\n", errno);
1903     } else {
1904         snprintf(g_capabilities.vendor_name, sizeof(g_capabilities.vendor_name),
1905                     "%s", value);
1906         if (value != NULL) {
1907             free(value);
1908         }
1909     }
1910
1911
1912     // Target name of the launch possible
1913     if(!request_capability_to_plugin(CAPABILITY_CAN_LAUNCH, g_capabilities.can_launch,
1914                             sizeof(g_capabilities.can_launch))) {
1915         E("failed to request. (%d:%d) \n", PLUGIN_SYNC_CMD_CAPABILITY, CAPABILITY_CAN_LAUNCH);
1916         snprintf(g_capabilities.can_launch, sizeof(g_capabilities.can_launch),
1917                     "%s", UNKNOWN);
1918     }
1919
1920
1921     // Device name
1922     value = vconf_get_str(VCONFKEY_SETAPPL_DEVICE_NAME_STR);
1923     if(value) {
1924         snprintf(g_capabilities.device_name, sizeof(g_capabilities.device_name),
1925                 "%s", value);
1926         if (value != NULL) {
1927             free(value);
1928         }
1929     } else {
1930         snprintf(g_capabilities.device_name, sizeof(g_capabilities.device_name),
1931                 "%s", UNKNOWN);
1932         E("fail to get the Device name:%d\n", errno);
1933     }
1934
1935
1936     // Platform version
1937     ret = system_info_get_platform_string("http://tizen.org/feature/platform.version", &value);
1938     if (ret != SYSTEM_INFO_ERROR_NONE) {
1939         snprintf(g_capabilities.platform_version, sizeof(g_capabilities.platform_version),
1940                     "%s", UNKNOWN);
1941         E("fail to get platform version:%d\n", errno);
1942     } else {
1943         snprintf(g_capabilities.platform_version, sizeof(g_capabilities.platform_version),
1944                     "%s", value);
1945         if (value != NULL) {
1946             free(value);
1947         }
1948     }
1949
1950
1951     // Product version
1952     if(!request_capability_to_plugin(CAPABILITY_PRODUCT_VER, g_capabilities.product_version,
1953                             sizeof(g_capabilities.product_version))) {
1954         E("failed to request. (%d:%d) \n", PLUGIN_SYNC_CMD_CAPABILITY, CAPABILITY_PRODUCT_VER);
1955         snprintf(g_capabilities.product_version, sizeof(g_capabilities.product_version),
1956                     "%s", UNKNOWN);
1957     }
1958
1959
1960     // Sdbd version
1961     snprintf(g_capabilities.sdbd_version, sizeof(g_capabilities.sdbd_version),
1962                 "%d.%d.%d", SDB_VERSION_MAJOR, SDB_VERSION_MINOR, SDB_VERSION_PATCH);
1963
1964
1965     // Sdbd plugin version
1966     if(!request_capability_to_plugin(CAPABILITY_PLUGIN_VER, g_capabilities.sdbd_plugin_version,
1967                             sizeof(g_capabilities.sdbd_plugin_version))) {
1968         E("failed to request. (%d:%d) \n", PLUGIN_SYNC_CMD_CAPABILITY, CAPABILITY_PLUGIN_VER);
1969         snprintf(g_capabilities.sdbd_plugin_version, sizeof(g_capabilities.sdbd_plugin_version),
1970                     "%s", UNKNOWN);
1971     }
1972
1973
1974     // sdbd log enable
1975     if(!request_capability_to_plugin(CAPABILITY_LOG_ENABLE, g_capabilities.log_enable,
1976                                sizeof(g_capabilities.log_enable))) {
1977            E("failed to request. (%d:%d) \n", PLUGIN_SYNC_CMD_CAPABILITY, CAPABILITY_LOG_ENABLE);
1978            snprintf(g_capabilities.log_enable, sizeof(g_capabilities.log_enable),
1979                        "%s", DISABLED);
1980     }
1981
1982     // sdbd log path
1983     if(!request_capability_to_plugin(CAPABILITY_LOG_PATH, g_capabilities.log_path,
1984                                sizeof(g_capabilities.log_path))) {
1985            E("failed to request. (%d:%d) \n", PLUGIN_SYNC_CMD_CAPABILITY, CAPABILITY_LOG_PATH);
1986            snprintf(g_capabilities.log_path, sizeof(g_capabilities.log_path),
1987                        "%s", UNKNOWN);
1988     }
1989
1990     // Application command support
1991     if(!request_capability_to_plugin(CAPABILITY_APPCMD, g_capabilities.appcmd_support,
1992                                sizeof(g_capabilities.appcmd_support))) {
1993            E("failed to request. (%d:%d) \n", PLUGIN_SYNC_CMD_CAPABILITY, CAPABILITY_APPCMD);
1994            snprintf(g_capabilities.appcmd_support, sizeof(g_capabilities.appcmd_support),
1995                        "%s", UNKNOWN);
1996     }
1997
1998     // appid2pid support
1999     ret = is_appid2pid_supported();
2000     snprintf(g_capabilities.appid2pid_support, sizeof(g_capabilities.appid2pid_support),
2001                 "%s", ret == 1 ? ENABLED : DISABLED);
2002
2003     // pkgcmd debug mode support
2004     if(!request_capability_to_plugin(CAPABILITY_DEBUGMODE, g_capabilities.pkgcmd_debugmode,
2005                 sizeof(g_capabilities.pkgcmd_debugmode))) {
2006         E("failed to request. (%d:%d) \n", PLUGIN_SYNC_CMD_CAPABILITY, CAPABILITY_DEBUGMODE);
2007         snprintf(g_capabilities.pkgcmd_debugmode, sizeof(g_capabilities.pkgcmd_debugmode),
2008                 "%s", ENABLED);
2009     }
2010
2011     // netcore debugger support
2012     ret = is_netcoredbg_supported();
2013     snprintf(g_capabilities.netcoredbg_support, sizeof(g_capabilities.netcoredbg_support),
2014              "%s", ret == 1 ? ENABLED : DISABLED);
2015
2016     // Capability version
2017     snprintf(g_capabilities.sdbd_cap_version, sizeof(g_capabilities.sdbd_cap_version),
2018                 "%d.%d", SDBD_CAP_VERSION_MAJOR, SDBD_CAP_VERSION_MINOR);
2019 }
2020
2021 static int is_support_usbproto()
2022 {
2023     return (!strncmp(g_capabilities.usbproto_support, PLUGIN_RET_ENABLED, strlen(PLUGIN_RET_ENABLED)));
2024 }
2025
2026 static int is_support_sockproto()
2027 {
2028     return (!strncmp(g_capabilities.sockproto_support, PLUGIN_RET_ENABLED, strlen(PLUGIN_RET_ENABLED)));
2029 }
2030
2031 #define EMULATOR_MODEL_NAME     "Emulator"
2032 static void check_emulator_or_device()
2033 {
2034     char model_name[256]={0,};
2035     int ret = -1;
2036
2037     // Get the model name from model_config.xml
2038     ret = get_device_name(model_name, sizeof model_name);
2039     if (ret == 0) {
2040         if(!strncmp(model_name, EMULATOR_MODEL_NAME, sizeof(EMULATOR_MODEL_NAME))){
2041             g_is_emulator = 1;
2042             I("This target type is Emulator\n");
2043         } else {
2044             g_is_emulator = 0;
2045             I("This target type is Device\n");
2046         }
2047     } else {
2048         g_is_emulator = -1;
2049         E("failed to get the model name.\n");
2050     }
2051 }
2052
2053 static void fork_prepare_handler(void)
2054 {
2055     sdb_mutex_lock(&D_lock);
2056 }
2057
2058 static void fork_parent_handler(void)
2059 {
2060     sdb_mutex_unlock(&D_lock);
2061 }
2062
2063 static void fork_child_handler(void)
2064 {
2065     sdb_mutex_unlock(&D_lock);
2066 }
2067
2068 int sdb_main(int server_port)
2069 {
2070     check_emulator_or_device();
2071
2072     load_sdbd_plugin();
2073
2074     init_capabilities();
2075
2076     //sdb_trace_init();
2077     //start_device_log();
2078
2079     init_drop_privileges();
2080     init_sdk_requirements();
2081     if (!request_validity_to_plugin(PLUGIN_SYNC_CMD_VERIFY_LAUNCH, NULL)) {
2082         E("sdbd should be launched in develop mode.\n");
2083         return -1;
2084     }
2085
2086     umask(000);
2087
2088     pthread_atfork(fork_prepare_handler, fork_parent_handler, fork_child_handler);
2089
2090     atexit(sdb_cleanup);
2091 #if defined(HAVE_FORKEXEC)
2092     // No SIGCHLD. Let the service subproc handle its children.
2093     signal(SIGPIPE, SIG_IGN);
2094 #endif
2095
2096     init_transport_registration();
2097
2098     /* don't listen on a port (default 5037) if running in secure mode */
2099     /* don't run as root if we are running in secure mode */
2100
2101     if (should_drop_privileges()) {
2102 # if 0
2103         struct __user_cap_header_struct header;
2104         struct __user_cap_data_struct cap;
2105
2106         if (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0) != 0) {
2107             exit(1);
2108         }
2109         /* add extra groups:
2110         ** SID_TTY to access /dev/ptmx
2111         */
2112         gid_t groups[] = { SID_TTY, SID_APP_LOGGING, SID_SYS_LOGGING };
2113         if (setgroups(sizeof(groups)/sizeof(groups[0]), groups) != 0) {
2114             exit(1);
2115         }
2116         /* then switch user and group to "developer" */
2117         if (setgid(GID_DEVELOPER) != 0) {
2118             fprintf(stderr, "set group id failed errno: %d\n", errno);
2119             exit(1);
2120         }
2121         if (setuid(SID_DEVELOPER) != 0) {
2122             fprintf(stderr, "set user id failed errno: %d\n", errno);
2123             exit(1);
2124         }
2125
2126         /* set CAP_SYS_BOOT capability, so "sdb reboot" will succeed */
2127         header.version = _LINUX_CAPABILITY_VERSION;
2128         header.pid = 0;
2129         cap.effective = cap.permitted = (1 << CAP_SYS_BOOT);
2130         cap.inheritable = 0;
2131         capset(&header, &cap);
2132 #endif
2133         I("Local port disabled\n");
2134     } else {
2135         char local_name[30];
2136         build_local_name(local_name, sizeof(local_name), server_port);
2137         if(install_listener(local_name, "*smartsocket*", NULL)) {
2138             exit(1);
2139         }
2140     }
2141
2142     /* choose the usb gadget backend */
2143     if (access(USB_NODE_FILE, F_OK) == 0) {
2144         /* legacy kernel-based sdb gadget */
2145         usb_init =    &linux_usb_init;
2146         usb_cleanup = &linux_usb_cleanup;
2147         usb_write =   &linux_usb_write;
2148         usb_read =    &linux_usb_read;
2149         usb_close =   &linux_usb_close;
2150         usb_kick =    &linux_usb_kick;
2151     } else {
2152         /* functionfs based gadget */
2153         usb_init =    &ffs_usb_init;
2154         usb_cleanup = &ffs_usb_cleanup;
2155         usb_write =   &ffs_usb_write;
2156         usb_read =    &ffs_usb_read;
2157         usb_close =   &ffs_usb_close;
2158         usb_kick =    &ffs_usb_kick;
2159     }
2160
2161     if (is_support_usbproto()) {
2162         // listen on USB
2163         usb_init();
2164     }
2165     if (is_support_sockproto()) {
2166         /* by default don't listen on local transport but
2167          * listen if suitable command line argument has been provided */
2168         if (sdbd_commandline_args.sdbd_port >= 0) {
2169             local_init(sdbd_commandline_args.sdbd_port);
2170         } else {
2171             local_init(DEFAULT_SDB_LOCAL_TRANSPORT_PORT);
2172         }
2173     }
2174
2175 #if 0 /* tizen specific */
2176     D("sdb_main(): pre init_jdwp()\n");
2177     init_jdwp();
2178     D("sdb_main(): post init_jdwp()\n");
2179 #endif
2180
2181     sdb_notify_startup(0, "READY=1");
2182
2183     I("Event loop starting\n");
2184
2185     fdevent_loop();
2186
2187     if (is_support_usbproto()) {
2188         usb_cleanup();
2189     }
2190
2191     return 0;
2192 }
2193
2194 int copy_packet(apacket* dest, apacket* src) {
2195
2196     if(dest == NULL) {
2197         E("dest packet is NULL\n");
2198         return -1;
2199     }
2200
2201     if(src == NULL) {
2202         E("src packet is NULL\n");
2203         return -1;
2204     }
2205
2206     dest->next = src->next;
2207     dest->ptr = src->ptr;
2208     dest->len = src->len;
2209
2210     int data_length = src->msg.data_length;
2211     if(data_length > MAX_PAYLOAD) {
2212         data_length = MAX_PAYLOAD;
2213     }
2214     memcpy(&(dest->msg), &(src->msg), sizeof(amessage) + data_length);
2215
2216     return 0;
2217 }
2218
2219 int handle_host_request(char *service, transport_type ttype, char* serial, int reply_fd, asocket *s)
2220 {
2221     atransport *transport = NULL;
2222     char buf[4096];
2223
2224     if(!strcmp(service, "kill")) {
2225         fprintf(stderr,"sdb server killed by remote request\n");
2226         fflush(stdout);
2227         sdb_write(reply_fd, "OKAY", 4);
2228         if (is_support_usbproto()) {
2229             usb_cleanup();
2230         }
2231         exit(0);
2232     }
2233
2234     if(!strncmp(service,"forward:",8) || !strncmp(service,"killforward:",12)) {
2235         char *local, *remote, *err;
2236         int r;
2237         atransport *transport;
2238
2239         int createForward = strncmp(service,"kill",4);
2240
2241         local = service + (createForward ? 8 : 12);
2242         remote = strchr(local,';');
2243         if(remote == 0) {
2244             sendfailmsg(reply_fd, "malformed forward spec");
2245             return 0;
2246         }
2247
2248         *remote++ = 0;
2249         if((local[0] == 0) || (remote[0] == 0) || (remote[0] == '*')){
2250             sendfailmsg(reply_fd, "malformed forward spec");
2251             return 0;
2252         }
2253
2254         transport = acquire_one_transport(CS_ANY, ttype, serial, &err);
2255         if (!transport) {
2256             sendfailmsg(reply_fd, err);
2257             return 0;
2258         }
2259
2260         if (createForward) {
2261             r = install_listener(local, remote, transport);
2262         } else {
2263             r = remove_listener(local, remote, transport);
2264         }
2265         if(r == 0) {
2266                 /* 1st OKAY is connect, 2nd OKAY is status */
2267             writex(reply_fd, "OKAYOKAY", 8);
2268             return 0;
2269         }
2270
2271         if (createForward) {
2272             sendfailmsg(reply_fd, (r == -1) ? "cannot rebind smartsocket" : "cannot bind socket");
2273         } else {
2274             sendfailmsg(reply_fd, "cannot remove listener");
2275         }
2276         return 0;
2277     }
2278
2279     if(!strncmp(service,"get-state",strlen("get-state"))) {
2280         transport = acquire_one_transport(CS_ANY, ttype, serial, NULL);
2281         char *state = connection_state_name(transport);
2282         snprintf(buf, sizeof buf, "OKAY%04x%s",(unsigned)strlen(state),state);
2283         writex(reply_fd, buf, strlen(buf));
2284         return 0;
2285     }
2286     return -1;
2287 }
2288
2289 int recovery_mode = 0;
2290
2291 int main(int argc, char **argv)
2292 {
2293     /* If sdbd runs inside the emulator this will enable sdb tracing via
2294      * sdb-debug qemud service in the emulator. */
2295 #if 0 /* tizen specific */
2296     sdb_qemu_trace_init();
2297     if((argc > 1) && (!strcmp(argv[1],"recovery"))) {
2298         sdb_device_banner = "recovery";
2299         recovery_mode = 1;
2300     }
2301 #endif
2302
2303     apply_sdbd_commandline_defaults(&sdbd_commandline_args);
2304     int parse_ret = parse_sdbd_commandline(&sdbd_commandline_args, argc, argv);
2305
2306     // TODO: Add detailed error messages
2307     // TODO: Add individual messages for help and usage
2308     if(parse_ret != SDBD_COMMANDLINE_SUCCESS) {
2309         if (parse_ret == SDBD_COMMANDLINE_HELP
2310                 || parse_ret == SDBD_COMMANDLINE_USAGE) {
2311             // User requested help or usage
2312             print_sdbd_usage_message(stdout);
2313             return EXIT_SUCCESS;
2314         }
2315
2316         // Print usage message because of invalid options
2317         print_sdbd_usage_message(stderr);
2318         return EXIT_FAILURE;
2319     }
2320
2321     I("Handling main()\n");
2322
2323     //sdbd will never die on emulator!
2324     signal(SIGTERM, handle_sig_term); /* tizen specific */
2325     return sdb_main(DEFAULT_SDB_PORT);
2326 }