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