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