Modify the SMACK label for SDB shell.
[sdk/target/sdbd.git] / src / default_plugin_appcmd.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 #include <stdlib.h>
18 #include <stdio.h>
19 #include <unistd.h>
20 #include <string.h>
21 #include <errno.h>
22
23 #define TRACE_TAG  TRACE_APPCMD
24
25 #include "sysdeps.h"
26 #include "sdb.h"
27 #include "strutils.h"
28 #include "utils.h"
29 #include "log.h"
30
31 #include "parameter.h"
32 #include "sdbd_plugin.h"
33
34 #if APPCMD_USING_PKGMGR
35 #include <pkgmgr-info.h>
36 #include <package-manager.h>
37 #endif
38
39 #include <tzplatform_config.h>
40
41 #define SHELL_COMMAND   "/bin/sh"
42 #define APPCMD_RESULT_BUFSIZE   (4096)
43
44 typedef struct appcmd_info appcmd_info;
45 typedef int (*appcmd_gen_shellcmd)(appcmd_info*);
46 typedef void (*appcmd_receiver)(int, int);
47 struct appcmd_info {
48     int fd;
49
50     char* args[MAX_TOKENS];
51     size_t args_cnt;
52     char* raw_command;
53
54     appcmd_gen_shellcmd gen_cmd_func;
55     appcmd_receiver receiver_func;
56
57     char shell_cmd[SDBD_SHELL_CMD_MAX];
58
59     int exitcode;
60 };
61
62 static int appcmd_install_gen_shellcmd(appcmd_info* p_info) {
63     char *type = NULL;
64     char *pkgpath = NULL;
65     char *pkgid = NULL;
66     char *teppath = NULL;
67     char *buf = p_info->shell_cmd;
68     int len = sizeof(p_info->shell_cmd);
69
70     if (p_info->args_cnt != 5) {
71         D("failed to parse appcmd.(cnt=%d)\n", p_info->args_cnt);
72         return -1;
73     }
74
75     type = p_info->args[1];
76     pkgpath = p_info->args[2];
77     pkgid = p_info->args[3];
78     teppath = p_info->args[4];
79
80     D("args: type=%s, pkgpath=%s, pkgid=%s, teppath=%s\n", type, pkgpath, pkgid, teppath);
81
82     if (strncmp(pkgid, "null", 4) == 0) {
83         if (strncmp(teppath, "null", 4) == 0) {
84             /* Normal install case */
85             snprintf(buf, len, "pkgcmd -i -q -t %s -p %s -G", type, pkgpath);
86         } else {
87             /* TEP install case */
88             snprintf(buf, len, "pkgcmd -i -q -p %s -e %s -G", pkgpath, teppath);
89         }
90     } else {
91         /* Re-install case */
92         snprintf(buf, len, "pkgcmd -r -q -t %s -n %s", type, pkgid);
93     }
94
95     return 0;
96 }
97
98 static int appcmd_uninstall_gen_shellcmd(appcmd_info* p_info) {
99     char *pkgid = NULL;
100     char *buf = p_info->shell_cmd;
101     int len = sizeof(p_info->shell_cmd);
102
103     if (p_info->args_cnt != 2) {
104         D("failed to parse appcmd.(cnt=%d)\n", p_info->args_cnt);
105         return -1;
106     }
107
108     pkgid = p_info->args[1];
109
110     D("args: pkgid=%s\n", pkgid);
111
112     snprintf(buf, len, "pkgcmd -u -q -n %s", pkgid);
113
114     return 0;
115 }
116
117 static int appcmd_runapp_gen_shellcmd(appcmd_info* p_info) {
118     char *appid = NULL;
119     char *buf = p_info->shell_cmd;
120     int len = sizeof(p_info->shell_cmd);
121
122     if (p_info->args_cnt != 2) {
123         D("failed to parse appcmd.(cnt=%d)\n", p_info->args_cnt);
124         return -1;
125     }
126
127     appid = p_info->args[1];
128
129     D("args: appid=%s\n", appid);
130
131     snprintf(buf, len, "/usr/bin/app_launcher --start %s", appid);
132
133     return 0;
134 }
135
136 static int appcmd_rununittestapp_gen_shellcmd(appcmd_info* p_info) {
137     char *appid = NULL;
138     char *usr_args = NULL;
139     char *buf = p_info->shell_cmd;
140     int len = sizeof(p_info->shell_cmd);
141     char *ptr = NULL;
142     char *p_service = NULL;
143     char *p_appid = NULL;
144
145     free_strings(p_info->args, p_info->args_cnt);
146
147     p_service = strtok_r(p_info->raw_command, ":", &ptr);
148     p_appid = strtok_r(NULL, ":", &ptr);
149     if (p_service == NULL || p_appid == NULL) {
150         D("failed to parse appcmd.(cnt=%d)\n", p_info->args_cnt);
151         return -1;
152     }
153
154     p_info->args_cnt = 3;
155     p_info->args[0] = strdup(p_service);
156     p_info->args[1] = strdup(p_appid);
157     p_info->args[2] = strdup(ptr);
158
159     appid = p_info->args[1];
160     usr_args = p_info->args[2];
161
162     D("args: appid=%s, usr_args=%s\n", appid, usr_args);
163
164     snprintf(buf, len, "/usr/bin/app_launcher -s %s __AUL_SDK__ UNIT_TEST __LAUNCH_APP_MODE__ SYNC __DLP_UNIT_TEST_ARG__ \'%s\'", appid, usr_args);
165
166     return 0;
167 }
168
169 static int appcmd_killapp_gen_shellcmd(appcmd_info* p_info) {
170     char *appid = NULL;
171     char *buf = p_info->shell_cmd;
172     int len = sizeof(p_info->shell_cmd);
173
174     if (p_info->args_cnt != 2) {
175         D("failed to parse appcmd.(cnt=%d)\n", p_info->args_cnt);
176         return -1;
177     }
178
179     appid = p_info->args[1];
180
181     D("args: appid=%s\n", appid);
182
183     snprintf(buf, len, "/usr/bin/app_launcher --kill %s", appid);
184
185     return 0;
186 }
187
188 static int appcmd_packagelist_gen_shellcmd(appcmd_info* p_info) {
189     char *type = NULL;
190     char *buf = p_info->shell_cmd;
191     int len = sizeof(p_info->shell_cmd);
192
193     if (p_info->args_cnt != 2) {
194         D("failed to parse appcmd.(cnt=%d)\n", p_info->args_cnt);
195         return -1;
196     }
197
198     type = p_info->args[1];
199
200     D("args: type=%s\n", type);
201
202     snprintf(buf, len, "/usr/bin/pkgcmd -l -t %s", type);
203
204     return 0;
205 }
206
207 static int appcmd_debugwebapp_gen_shellcmd(appcmd_info* p_info) {
208     char *appid = NULL;
209     char *buf = p_info->shell_cmd;
210     int len = sizeof(p_info->shell_cmd);
211
212     if (p_info->args_cnt != 2) {
213         D("failed to parse appcmd.(cnt=%d)\n", p_info->args_cnt);
214         return -1;
215     }
216
217     appid = p_info->args[1];
218
219     D("args: appid=%s\n", appid);
220
221     snprintf(buf, len, "/usr/bin/app_launcher --start %s -w", appid);
222
223     return 0;
224 }
225
226 static int appcmd_debugnativeapp_gen_shellcmd(appcmd_info* p_info) {
227     char *debug_port = NULL;
228     char *appid= NULL;
229     char *pid_str = NULL;
230     char *gdbserver_path = NULL;
231     char *buf = p_info->shell_cmd;
232     int pid = -1;
233     int len = sizeof(p_info->shell_cmd);
234
235     if (p_info->args_cnt != 5) {
236         D("failed to parse appcmd.(cnt=%d)\n", p_info->args_cnt);
237         return -1;
238     }
239
240     debug_port = p_info->args[1];
241     appid= p_info->args[2];
242     pid_str = p_info->args[3];
243     gdbserver_path = p_info->args[4]; // not used. for 3.0 platform.
244
245     pid = atoi(pid_str);
246     D("args: debug_port=%s, appid=%s, pid=%d, gdbserver_path=%s\n", debug_port, appid, pid, gdbserver_path);
247
248     if (pid == -1) {
249         snprintf(buf, len, "/usr/bin/app_launcher --start %s __AUL_SDK__ DEBUG __DLP_DEBUG_ARG__ :%s __DLP_GDBSERVER_PATH__ %s", appid, debug_port, gdbserver_path);
250     } else {
251         /* attach mode */
252         snprintf(buf, len, "/usr/bin/launch_debug %s __AUL_SDK__ ATTACH __DLP_GDBSERVER_PATH__ %s __DLP_ATTACH_ARG__ --attach,:%s,%d", appid, gdbserver_path, debug_port, pid);
253     }
254
255     return 0;
256 }
257
258 static int appcmd_appinfo_gen_shellcmd(appcmd_info* p_info) {
259     char *pkgid = NULL;
260     char *buf = p_info->shell_cmd;
261     int len = sizeof(p_info->shell_cmd);
262
263     if (p_info->args_cnt != 2) {
264         D("failed to parse appcmd.(cnt=%d)\n", p_info->args_cnt);
265         return -1;
266     }
267
268     pkgid = p_info->args[1];
269
270     D("args: pkgid=%s\n", pkgid);
271
272     snprintf(buf, len, "/usr/bin/pkginfo --list %s", pkgid);
273
274     return 0;
275 }
276
277 static void appcmd_receiver_debugwebapp(int fd_in, int fd_out)
278 {
279     char buf[4096] = {0,};
280     char port_str[32] = {0,};
281     char out_buf[128] = {0,};
282     char* sub_str = NULL;
283     int r;
284
285     for(;;) {
286         memset(buf, 0, sizeof(buf));
287         r = read_line(fd_in, buf, sizeof(buf));
288         if (r == 0) {
289             break;
290         } else if(r < 0) {
291             if (errno == EINTR) {
292                 continue;
293             } else {
294                 break;
295             }
296         }
297
298         D("debug webapp output : %s\n", buf);
299         sub_str = strstr(buf, "port: ");
300         if (sub_str != NULL && sscanf(sub_str, "port: %s", port_str) == 1) {
301             snprintf(out_buf, sizeof(out_buf), "\n%s:%s\n", MESSAGE_PREFIX_APPCMD_RETURN, port_str);
302             writex(fd_out, out_buf, strlen(out_buf)+1);
303             break;
304         }
305     }
306 }
307
308 static void appcmd_receiver_default(int fd_in, int fd_out)
309 {
310     char buf[4096] = {0,};
311     int r;
312
313     for(;;) {
314         memset(buf, 0, sizeof(buf));
315         r = sdb_read(fd_in, buf, sizeof(buf));
316         if (r == 0) {
317             break;
318         } else if(r < 0) {
319             if (errno == EINTR) {
320                 continue;
321             } else {
322                 break;
323             }
324         }
325
326         writex(fd_out, buf, strlen(buf)+1);
327     }
328 }
329
330 static void appcmd_receiver_packagelist(int fd_in, int fd_out)
331 {
332     char buf[4096] = {0,};
333     char out_buf[4096] = {0,};
334     int out_ptr = 0;
335     int r;
336
337     snprintf(out_buf, sizeof(out_buf), "\n%s", MESSAGE_PREFIX_APPCMD_RETURN);
338     out_ptr = strlen(out_buf);
339
340     for(;;) {
341         memset(buf, 0, sizeof(buf));
342         r = read_line(fd_in, buf, sizeof(buf));
343         if (r == 0) {
344             break;
345         } else if(r < 0) {
346             if (errno == EINTR) {
347                 continue;
348             } else {
349                 break;
350             }
351         }
352
353         D("pkgcmd output : %s\n", buf);
354         char* sub1 = NULL;
355         char* sub2 = NULL;
356         sub1 = strstr(buf, "pkgid [");
357         if (sub1 != NULL) {
358             sub1 = strstr(sub1, "[")+1;
359             sub2 = strstr(sub1, "]");
360             sub2[0] = '\0';
361
362             snprintf(out_buf+out_ptr, sizeof(out_buf)-out_ptr, ":%s", sub1);
363             out_ptr += strlen(sub1)+1;
364         }
365     }
366
367     snprintf(out_buf+out_ptr, sizeof(out_buf)-out_ptr, "\n");
368
369     D("package list: %s\n", out_buf);
370     writex(fd_out, out_buf, strlen(out_buf)+1);
371 }
372
373 static void appcmd_receiver_appinfo(int fd_in, int fd_out)
374 {
375     char buf[4096] = {0,};
376     char out_buf[4096] = {0,};
377     char appid[128] = {0,};
378     char apptype[128] = {0,};
379     int out_ptr = 0;
380     int r;
381
382     snprintf(out_buf, sizeof(out_buf), "\n%s", MESSAGE_PREFIX_APPCMD_RETURN);
383     out_ptr = strlen(out_buf);
384
385     for(;;) {
386         memset(buf, 0, sizeof(buf));
387         r = read_line(fd_in, buf, sizeof(buf));
388         if (r == 0) {
389             break;
390         } else if(r < 0) {
391             if (errno == EINTR) {
392                 continue;
393             } else {
394                 break;
395             }
396         }
397
398         D("pkginfo output : %s\n", buf);
399
400         if (!strncmp(buf, "Appid: ", 7)) {
401             memset(appid, 0, sizeof(appid));
402             sscanf(buf, "Appid: %s", appid);
403
404             snprintf(out_buf+out_ptr, sizeof(out_buf)-out_ptr, ":%s", appid);
405             out_ptr += strlen(appid)+1;
406         } else if (!strncmp(buf, "Apptype: ", 9)) {
407             memset(apptype, 0, sizeof(apptype));
408             sscanf(buf, "Apptype: %s", apptype);
409
410             snprintf(out_buf+out_ptr, sizeof(out_buf)-out_ptr, ":%s", apptype);
411             out_ptr += strlen(apptype)+1;
412         }
413     }
414
415     snprintf(out_buf+out_ptr, sizeof(out_buf)-out_ptr, "\n");
416
417     D("app info: %s\n", out_buf);
418     writex(fd_out, out_buf, strlen(out_buf)+1);
419 }
420
421 static int exec_appcmd_shell_process(appcmd_info* p_info) {
422     int ptm_fd = -1;
423     pid_t pid;
424     char *value = NULL;
425     char *trim_value = NULL;
426     char path[PATH_MAX];
427     memset(path, 0, sizeof(path));
428
429     char *envp[] = {
430         "TERM=linux", /* without this, some programs based on screen can't work, e.g. top */
431         "DISPLAY=:0", /* without this, some programs based on without launchpad can't work */
432         NULL,
433         NULL,
434         NULL,
435         NULL,
436         NULL
437     };
438
439     // For the SDK user privilege.
440     envp[2] = "HOME=/home/developer";
441     get_env("ENV_PATH", &value);
442     if (value != NULL) {
443         trim_value = str_trim(value);
444         if (trim_value != NULL) {
445             // if string is not including 'PATH=', append it.
446             if (strncmp(trim_value, "PATH", 4)) {
447                 snprintf(path, sizeof(path), "PATH=%s", trim_value);
448             } else {
449                 snprintf(path, sizeof(path), "%s", trim_value);
450             }
451             envp[3] = path;
452             free(trim_value);
453         } else {
454             envp[3] = value;
455         }
456     }
457
458     D("path env:%s,%s,%s,%s\n", envp[0], envp[1], envp[2], envp[3]);
459
460     char *args[] = {
461         SHELL_COMMAND,
462         "-c",
463         NULL,
464         NULL,
465     };
466     args[2] = p_info->shell_cmd;
467
468     ptm_fd = create_subprocess(SHELL_COMMAND, &pid, (char * const*)args, (char * const*)envp);
469     D("create_subprocess() ptm_fd=%d pid=%d\n", ptm_fd, pid);
470     if (ptm_fd < 0) {
471         D("cannot create service thread\n");
472         return -1;
473     }
474
475     if (p_info->receiver_func != NULL) {
476         p_info->receiver_func(ptm_fd, p_info->fd);
477     }
478
479     // wait for shell process
480     for (;;) {
481         int status;
482         pid_t p = waitpid(pid, &status, 0);
483         if (p == pid) {
484             D("fd=%d, post waitpid(pid=%d) status=%04x\n", p_info->fd, p, status);
485
486             if (WIFEXITED(status)) {
487                 p_info->exitcode = WEXITSTATUS(status);
488                 D("*** Exit code %d\n", p_info->exitcode);
489                 break;
490             }
491         }
492     }
493     D("shell exited fd=%d of pid=%d err=%d\n", p_info->fd, pid, errno);
494
495     return 0;
496 }
497
498 #if APPCMD_USING_PKGMGR
499 static int get_pkg_info(char* pkgid, char* pkginfo_buf, int buf_size) {
500     pkgmgrinfo_pkginfo_h handle;
501     pkgmgr_client* pc = NULL;
502     char* pkgname = NULL;
503     char* type = NULL;
504     bool is_removable = 0;
505     int is_running = 0;
506     int ret = -1;
507     int pid = -1;
508
509     ret = pkgmgrinfo_pkginfo_get_pkginfo(pkgid, &handle);
510     if (ret < 0) {
511         D("failed to get pkginfo handle.\n");
512         return -1;
513     }
514
515     ret = pkgmgrinfo_pkginfo_get_mainappid(handle, &pkgname);
516     if (ret < 0) {
517         D("failed to get pkg name\n");
518         return -1;
519     }
520
521     ret = pkgmgrinfo_pkginfo_get_type(handle, &type);
522     if (ret < 0) {
523         D("failed to get pkg type.\n");
524         return -1;
525     }
526
527     ret = pkgmgrinfo_pkginfo_is_removable(handle, &is_removable);
528     if (ret < 0) {
529         D("failed to get removable info.\n");
530         return -1;
531     }
532
533     pc = pkgmgr_client_new(PC_REQUEST);
534     if (pc == NULL) {
535         D("failed to create pkgmgr client.\n");
536         return -1;
537     }
538
539     ret = pkgmgr_client_request_service(PM_REQUEST_CHECK_APP, 0, pc, NULL, pkgid, NULL, NULL, &pid);
540     if (ret < 0) {
541         D("failed to get running state.\n");
542         return -1;
543     }
544     is_running = ((pid > 0) ? 1:0);
545
546     D("pkginfo: pkgname=%s, type=%s, is_removagle=%d, is_running=%d, pid=%d\n", pkgname, type, is_removable, is_running, pid);
547     snprintf(pkginfo_buf, buf_size, "%s:%s:%d:%d", pkgname, type, is_removable, is_running);
548     return 0;
549 }
550
551 static void run_appcmd_packageinfo(appcmd_info* p_info) {
552     char result_buf[APPCMD_RESULT_BUFSIZE] = {0,};
553     char pkginfo_buf[256] = {0,};
554     char *type = NULL;
555     char *pkgid = NULL;
556
557     p_info->exitcode = -1;
558
559     if (p_info->args_cnt != 3) {
560         D("failed to parse appcmd.(cnt=%d)\n", p_info->args_cnt);
561         return;
562     }
563
564     type = p_info->args[1];
565     pkgid= p_info->args[2];
566
567     D("args: type=%s, pkgid=%s\n", type, pkgid);
568
569     if (get_pkg_info(pkgid, pkginfo_buf, sizeof(pkginfo_buf)) == 0) {
570         D("success to get pkginfo. (%s)\n", pkginfo_buf);
571         p_info->exitcode = 0;
572         snprintf(result_buf, sizeof(result_buf), "\n%s:%s\n", MESSAGE_PREFIX_APPCMD_RETURN, pkginfo_buf);
573         writex(p_info->fd, result_buf, strlen(result_buf));
574     } else {
575         D("failed to get pkginfo.\n");
576     }
577 }
578 #else
579 static int appcmd_packageinfo_gen_shellcmd(appcmd_info* p_info) {
580     char *pkgid = NULL;
581     char *buf = p_info->shell_cmd;
582     int len = sizeof(p_info->shell_cmd);
583
584     if (p_info->args_cnt != 2) {
585         D("failed to parse appcmd.(cnt=%d)\n", p_info->args_cnt);
586         return -1;
587     }
588
589     pkgid = p_info->args[1];
590
591     D("args: pkgid=%s\n", pkgid);
592
593     snprintf(buf, len, "/usr/bin/pkginfo --pkg %s;/usr/bin/pkgcmd -C -n %s", pkgid, pkgid);
594
595     return 0;
596 }
597
598 static void appcmd_receiver_packageinfo(int fd_in, int fd_out)
599 {
600     char buf[4096] = {0,};
601     char mainapp_id[128] = {0,};
602     char type[128] = {0,};
603     int is_removable = 0;
604     int is_running = 0;
605     int r;
606
607     for(;;) {
608         memset(buf, 0, sizeof(buf));
609         r = read_line(fd_in, buf, sizeof(buf));
610         if (r == 0) {
611             break;
612         } else if(r < 0) {
613             if (errno == EINTR) {
614                 continue;
615             } else {
616                 break;
617             }
618         }
619
620         if (!strncmp(buf, "mainappid : ", 12)) {
621             sscanf(buf, "mainappid : %s", mainapp_id);
622         } else if (!strncmp(buf, "Type: ", 6)) {
623             sscanf(buf, "Type: %s", type);
624         } else if (!strncmp(buf, "Removable: ", 11)) {
625             sscanf(buf, "Removable: %d", &is_removable);
626         } else if (strstr(buf, " is Running") != NULL) {
627             is_running = 1;
628         }
629     }
630
631     memset(buf, 0, sizeof(buf));
632     snprintf(buf, sizeof(buf), "\n%s:%s:%s:%d:%d\n",
633                 MESSAGE_PREFIX_APPCMD_RETURN, mainapp_id, type, is_removable, is_running);
634
635     D("package info: %s\n", buf);
636     writex(fd_out, buf, strlen(buf)+1);
637 }
638 #endif
639
640 static void run_appcmd_appinstallpath(appcmd_info* p_info) {
641     char result_buf[APPCMD_RESULT_BUFSIZE] = {0,};
642
643     p_info->exitcode = -1;
644
645     const char* path = tzplatform_getenv(TZ_SDK_TOOLS);
646     if (path != NULL) {
647         p_info->exitcode = 0;
648         snprintf(result_buf, sizeof(result_buf), "\n%s:%s\n", MESSAGE_PREFIX_APPCMD_RETURN, path);
649         writex(p_info->fd, result_buf, strlen(result_buf));
650     } else {
651         D("failed to get application install path from tzplatform_getenv.");
652     }
653 }
654
655 static void run_appcmd_with_shell_process(appcmd_info* p_info) {
656     int ret = -1;
657
658     if (p_info == NULL) {
659         D("Invalid arguments. p_info is null\n");
660         return;
661     }
662
663     if (p_info->gen_cmd_func == NULL) {
664         D("Invalid arguments.\n");
665         p_info->exitcode = -1;
666         return;
667     }
668
669     ret = p_info->gen_cmd_func(p_info);
670     if (ret < 0) {
671         D("failed to generate install shell command.\n");
672         p_info->exitcode = -1;
673     } else {
674         ret = exec_appcmd_shell_process(p_info);
675         D("exec_appcmd_shell_process: ret=%d, exitcode=%d\n", ret, p_info->exitcode);
676         if (ret < 0) {
677             D("failed to run shell process\n");
678             p_info->exitcode = -1;
679         }
680     }
681 }
682
683 int appcmd_service( parameters* in, int out_fd ) {
684     appcmd_info info;
685     char result_buf[APPCMD_RESULT_BUFSIZE] = {0,};
686     char* service_name = NULL;
687     char* command = NULL;
688
689     if (in == NULL || in->number_of_parameter != 1 || in->array_of_parameter == NULL
690             || in->array_of_parameter[0].type != type_string) {
691         D ( "Invalid argument\n" );
692         return PLUGIN_CMD_FAIL;
693     }
694
695     command = in->array_of_parameter[0].v_string.data;
696     D("command=%s(FD:%d)\n", command, out_fd);
697
698     memset(&info, 0, sizeof(info));
699
700     /* appcmd parameter data map
701      * "service name:arg1:arg2:...:argN" */
702     info.args_cnt = tokenize(command, ":", info.args, MAX_TOKENS);
703     D("args_cnt=%d\n", info.args_cnt);
704     if (info.args_cnt < 1) {
705         D("failed to parse appcmd for install. (%s)\n", command);
706         info.exitcode = -1;
707         goto appcmd_done;
708     }
709
710     info.fd = out_fd;
711     info.exitcode = -1;
712     info.raw_command = command;
713
714     service_name = info.args[0];
715     D("service name=%s\n", service_name);
716
717     if (strncmp(service_name, "install", 7) == 0) {
718         info.receiver_func = appcmd_receiver_default;
719         info.gen_cmd_func = appcmd_install_gen_shellcmd;
720         run_appcmd_with_shell_process(&info);
721         // remove pkg files
722         if (info.args[2] != NULL) {
723             sdb_unlink(info.args[2]);
724         }
725     } else if (strncmp(service_name, "uninstall", 9) == 0) {
726         info.receiver_func = appcmd_receiver_default;
727         info.gen_cmd_func = appcmd_uninstall_gen_shellcmd;
728         run_appcmd_with_shell_process(&info);
729     } else if (strncmp(service_name, "appinfo", 7) == 0) {
730         info.gen_cmd_func = appcmd_appinfo_gen_shellcmd;
731         info.receiver_func = appcmd_receiver_appinfo;
732         run_appcmd_with_shell_process(&info);
733     } else if (strncmp(service_name, "packageinfo", 11) == 0) {
734 #if APPCMD_USING_PKGMGR
735         run_appcmd_packageinfo(&info);
736 #else
737         info.gen_cmd_func = appcmd_packageinfo_gen_shellcmd;
738         info.receiver_func = appcmd_receiver_packageinfo;
739         run_appcmd_with_shell_process(&info);
740 #endif
741     } else if (strncmp(service_name, "packagelist", 11) == 0) {
742         info.gen_cmd_func = appcmd_packagelist_gen_shellcmd;
743         info.receiver_func = appcmd_receiver_packagelist;
744         run_appcmd_with_shell_process(&info);
745     } else if (strncmp(service_name, "appinstallpath", 14) == 0) {
746         run_appcmd_appinstallpath(&info);
747     } else if (strncmp(service_name, "runapp", 6) == 0) {
748         info.receiver_func = appcmd_receiver_default;
749         info.gen_cmd_func = appcmd_runapp_gen_shellcmd;
750         run_appcmd_with_shell_process(&info);
751     } else if (strncmp(service_name, "rununittestapp", 14) == 0) {
752         info.receiver_func = appcmd_receiver_default;
753         info.gen_cmd_func = appcmd_rununittestapp_gen_shellcmd;
754         run_appcmd_with_shell_process(&info);
755     } else if (strncmp(service_name, "killapp", 7) == 0) {
756         info.receiver_func = appcmd_receiver_default;
757         info.gen_cmd_func = appcmd_killapp_gen_shellcmd;
758         run_appcmd_with_shell_process(&info);
759     } else if (strncmp(service_name, "debugwebapp", 11) == 0) {
760         info.gen_cmd_func = appcmd_debugwebapp_gen_shellcmd;
761         info.receiver_func = appcmd_receiver_debugwebapp;
762         run_appcmd_with_shell_process(&info);
763     } else if (strncmp(service_name, "debugnativeapp", 14) == 0) {
764         info.gen_cmd_func = appcmd_debugnativeapp_gen_shellcmd;
765         run_appcmd_with_shell_process(&info);
766     } else {
767         D("not supported appcmd service. (%s)\n", service_name);
768         info.exitcode = -1;
769         goto appcmd_done;
770     }
771
772 appcmd_done:
773     free_strings(info.args, info.args_cnt);
774
775     snprintf(result_buf, sizeof(result_buf), "\n%s:%d\n", MESSAGE_PREFIX_APPCMD_EXITCODE, info.exitcode);
776     writex(out_fd, result_buf, strlen(result_buf));
777
778     if (info.exitcode != 0) {
779         return PLUGIN_CMD_FAIL;
780     }
781
782     return PLUGIN_CMD_SUCCESS;
783 }