2ed4198b713a3b4c1134abbf32834d7e3ab0dfd4
[framework/appfw/slp-pkgmgr.git] / tool / pkg_cmd.c
1
2 /*
3  * slp-pkgmgr
4  *
5  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
6  *
7  * Contact: Jayoun Lee <airjany@samsung.com>, Sewook Park <sewook7.park@samsung.com>,
8  * Jaeho Lee <jaeho81.lee@samsung.com>, Shobhit Srivastava <shobhit.s@samsung.com>
9  *
10  * Licensed under the Apache License, Version 2.0 (the "License");
11  * you may not use this file except in compliance with the License.
12  * You may obtain a copy of the License at
13  *
14  * http://www.apache.org/licenses/LICENSE-2.0
15  *
16  * Unless required by applicable law or agreed to in writing, software
17  * distributed under the License is distributed on an "AS IS" BASIS,
18  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19  * See the License for the specific language governing permissions and
20  * limitations under the License.
21  *
22  */
23
24 #define _GNU_SOURCE
25
26 #include <stdio.h>
27 #include <string.h>
28 #include <stdlib.h>
29 #include <unistd.h>
30 #include <ctype.h>
31 #include <getopt.h>
32 #include <dirent.h>
33 #include <fcntl.h>
34 #include <dlfcn.h>
35 #include <sys/types.h>
36 #include <glib.h>
37 #include <ail.h>
38 #include <glib-object.h>
39 #include <pkgmgr-info.h>
40 #include "package-manager.h"
41 #include "package-manager-types.h"
42
43 #define PKG_TOOL_VERSION        "0.1"
44 #define APP_INSTALLATION_PATH_RW        "/opt/usr/apps"
45
46 /* 1 -100 : Package command errors */
47 /* 101-120 : reserved for Core installer */
48 /* 121-140 : reserved for Web installer */
49 /* 141-160 : reserved for Native installer */
50 #define PKGCMD_ERR_PACKAGE_NOT_FOUND                                    1
51 #define PKGCMD_ERR_PACKAGE_INVALID                                              2
52 #define PKGCMD_ERR_PACKAGE_LOWER_VERSION                                3
53 #define PKGCMD_ERR_PACKAGE_EXECUTABLE_NOT_FOUND                 4
54 #define PKGCMD_ERR_MANIFEST_NOT_FOUND                                   11
55 #define PKGCMD_ERR_MANIFEST_INVALID                                             12
56 #define PKGCMD_ERR_CONFIG_NOT_FOUND                                             13
57 #define PKGCMD_ERR_CONFIG_INVALID                                               14
58 #define PKGCMD_ERR_SIGNATURE_NOT_FOUND                                  21
59 #define PKGCMD_ERR_SIGNATURE_INVALID                                    22
60 #define PKGCMD_ERR_SIGNATURE_VERIFICATION_FAILED                23
61 #define PKGCMD_ERR_ROOT_CERTIFICATE_NOT_FOUND                   31
62 #define PKGCMD_ERR_CERTIFICATE_INVALID                                  32
63 #define PKGCMD_ERR_CERTIFICATE_CHAIN_VERIFICATION_FAILED        33
64 #define PKGCMD_ERR_CERTIFICATE_EXPIRED                                  34
65 #define PKGCMD_ERR_INVALID_PRIVILEGE                                    41
66 #define PKGCMD_ERR_MENU_ICON_NOT_FOUND                                  51
67 #define PKGCMD_ERR_FATAL_ERROR                                                  61
68 #define PKGCMD_ERR_OUT_OF_STORAGE                                               62
69 #define PKGCMD_ERR_OUT_OF_MEMORY                                                63
70 #define PKGCMD_ERR_ARGUMENT_INVALID                                             64
71
72 #define PKGCMD_ERR_PACKAGE_NOT_FOUND_STR                                        "PACKAGE_NOT_FOUND"
73 #define PKGCMD_ERR_PACKAGE_INVALID_STR                                          "PACKAGE_INVALID"
74 #define PKGCMD_ERR_PACKAGE_LOWER_VERSION_STR                            "PACKAGE_LOWER_VERSION"
75 #define PKGCMD_ERR_PACKAGE_EXECUTABLE_NOT_FOUND_STR                     "PACKAGE_EXECUTABLE_NOT_FOUND"
76 #define PKGCMD_ERR_MANIFEST_NOT_FOUND_STR                                       "MANIFEST_NOT_FOUND"
77 #define PKGCMD_ERR_MANIFEST_INVALID_STR                                         "MANIFEST_INVALID"
78 #define PKGCMD_ERR_CONFIG_NOT_FOUND_STR                                         "CONFIG_NOT_FOUND"
79 #define PKGCMD_ERR_CONFIG_INVALID_STR                                           "CONFIG_INVALID"
80 #define PKGCMD_ERR_SIGNATURE_NOT_FOUND_STR                                      "SIGNATURE_NOT_FOUND"
81 #define PKGCMD_ERR_SIGNATURE_INVALID_STR                                        "SIGNATURE_INVALID"
82 #define PKGCMD_ERR_SIGNATURE_VERIFICATION_FAILED_STR            "SIGNATURE_VERIFICATION_FAILED"
83 #define PKGCMD_ERR_ROOT_CERTIFICATE_NOT_FOUND_STR                       "ROOT_CERTIFICATE_NOT_FOUND"
84 #define PKGCMD_ERR_CERTIFICATE_INVALID_STR                                      "CERTIFICATE_INVALID"
85 #define PKGCMD_ERR_CERTIFICATE_CHAIN_VERIFICATION_FAILED_STR    "CERTIFICATE_CHAIN_VERIFICATION_FAILED"
86 #define PKGCMD_ERR_CERTIFICATE_EXPIRED_STR                                      "CERTIFICATE_EXPIRED"
87 #define PKGCMD_ERR_INVALID_PRIVILEGE_STR                                        "INVALID_PRIVILEGE"
88 #define PKGCMD_ERR_MENU_ICON_NOT_FOUND_STR                                      "MENU_ICON_NOT_FOUND"
89 #define PKGCMD_ERR_FATAL_ERROR_STR                                                      "FATAL_ERROR"
90 #define PKGCMD_ERR_OUT_OF_STORAGE_STR                                           "OUT_OF_STORAGE"
91 #define PKGCMD_ERR_OUT_OF_MEMORY_STR                                            "OUT_OF_MEMORY"
92 #define PKGCMD_ERR_ARGUMENT_INVALID_STR                                         "ARGUMENT_INVALID"
93 #define PKGCMD_ERR_UNKNOWN_STR                                                          "Unknown Error"
94
95 static int __process_request();
96 static void __print_usage();
97 static int __is_authorized();
98 static int __is_app_installed(char *pkgid);
99 static void __print_pkg_info(pkgmgr_info * pkg_info);
100 static int __return_cb(int req_id, const char *pkg_type, const char *pkgid,
101                        const char *key, const char *val, const void *pmsg,
102                        void *data);
103 static int __convert_to_absolute_path(char *path);
104 static int __pkgcmd_read_proc(const char *path, char *buf, int size);
105 static int __pkgcmd_find_pid_by_cmdline(const char *dname,
106                         const char *cmdline, const char *apppath);
107 static int __pkgcmd_proc_iter_kill_cmdline(const char *apppath, int option);
108 static int __app_list_cb(const pkgmgr_appinfo_h handle, void *user_data);
109
110 /* Supported options */
111 const char *short_options = "iurmcCkaADL:lsd:p:t:n:T:qh";
112 const struct option long_options[] = {
113         {"install", 0, NULL, 'i'},
114         {"uninstall", 0, NULL, 'u'},
115         {"reinstall", 0, NULL, 'r'},
116         {"move", 0, NULL, 'm'},
117         {"clear", 0, NULL, 'c'},
118         {"activate", 0, NULL, 'A'},
119         {"deactivate", 0, NULL, 'D'},
120         {"activate with Label", 1, NULL, 'L'},
121         {"check", 0, NULL, 'C'},
122         {"kill", 0, NULL, 'k'},
123         {"app-path", 0, NULL, 'a'},
124         {"list", 0, NULL, 'l'},
125         {"show", 0, NULL, 's'},
126         {"descriptor", 1, NULL, 'd'},
127         {"package-path", 1, NULL, 'p'},
128         {"package-type", 1, NULL, 't'},
129         {"package-name", 1, NULL, 'n'},
130         {"move-type", 1, NULL, 'T'},
131         {"quiet", 0, NULL, 'q'},
132         {"help", 0, NULL, 'h'},
133         {0, 0, 0, 0}            /* sentinel */
134 };
135
136 enum pm_tool_request_e {
137         INSTALL_REQ = 1,
138         UNINSTALL_REQ,
139         REINSTALL_REQ,
140         CLEAR_REQ,
141         MOVE_REQ,
142         ACTIVATE_REQ,
143         DEACTIVATE_REQ,
144         APPPATH_REQ,
145         CHECKAPP_REQ,
146         KILLAPP_REQ,
147         LIST_REQ,
148         SHOW_REQ,
149         HELP_REQ
150 };
151 typedef enum pm_tool_request_e req_type;
152
153 struct pm_tool_args_t {
154         req_type request;
155         char pkg_path[PKG_NAME_STRING_LEN_MAX];
156         char pkg_type[PKG_TYPE_STRING_LEN_MAX];
157         char pkgid[PKG_NAME_STRING_LEN_MAX];
158         char des_path[PKG_NAME_STRING_LEN_MAX];
159         char label[PKG_NAME_STRING_LEN_MAX];
160         int quiet;
161         int move_type;
162         int result;
163 };
164 typedef struct pm_tool_args_t pm_tool_args;
165 pm_tool_args data;
166
167 static GMainLoop *main_loop = NULL;
168
169 static void __error_no_to_string(int errnumber, char **errstr)
170 {
171         if (errstr == NULL)
172                 return;
173         switch (errnumber) {
174         case PKGCMD_ERR_PACKAGE_NOT_FOUND:
175                 *errstr = PKGCMD_ERR_PACKAGE_NOT_FOUND_STR;
176                 break;
177         case PKGCMD_ERR_PACKAGE_INVALID:
178                 *errstr = PKGCMD_ERR_PACKAGE_INVALID_STR;
179                 break;
180         case PKGCMD_ERR_PACKAGE_LOWER_VERSION:
181                 *errstr = PKGCMD_ERR_PACKAGE_LOWER_VERSION_STR;
182                 break;
183         case PKGCMD_ERR_PACKAGE_EXECUTABLE_NOT_FOUND:
184                 *errstr = PKGCMD_ERR_PACKAGE_EXECUTABLE_NOT_FOUND_STR;
185                 break;
186         case PKGCMD_ERR_MANIFEST_INVALID:
187                 *errstr = PKGCMD_ERR_MANIFEST_INVALID_STR;
188                 break;
189         case PKGCMD_ERR_CONFIG_NOT_FOUND:
190                 *errstr = PKGCMD_ERR_CONFIG_NOT_FOUND_STR;
191                 break;
192         case PKGCMD_ERR_CONFIG_INVALID:
193                 *errstr = PKGCMD_ERR_CONFIG_INVALID_STR;
194                 break;
195         case PKGCMD_ERR_SIGNATURE_NOT_FOUND:
196                 *errstr = PKGCMD_ERR_SIGNATURE_NOT_FOUND_STR;
197                 break;
198         case PKGCMD_ERR_SIGNATURE_INVALID:
199                 *errstr = PKGCMD_ERR_SIGNATURE_INVALID_STR;
200                 break;
201         case PKGCMD_ERR_SIGNATURE_VERIFICATION_FAILED:
202                 *errstr = PKGCMD_ERR_SIGNATURE_VERIFICATION_FAILED_STR;
203                 break;
204         case PKGCMD_ERR_ROOT_CERTIFICATE_NOT_FOUND:
205                 *errstr = PKGCMD_ERR_ROOT_CERTIFICATE_NOT_FOUND_STR;
206                 break;
207         case PKGCMD_ERR_CERTIFICATE_INVALID:
208                 *errstr = PKGCMD_ERR_CERTIFICATE_INVALID_STR;
209                 break;
210         case PKGCMD_ERR_CERTIFICATE_CHAIN_VERIFICATION_FAILED:
211                 *errstr = PKGCMD_ERR_CERTIFICATE_CHAIN_VERIFICATION_FAILED_STR;
212                 break;
213         case PKGCMD_ERR_CERTIFICATE_EXPIRED:
214                 *errstr = PKGCMD_ERR_CERTIFICATE_EXPIRED_STR;
215                 break;
216         case PKGCMD_ERR_INVALID_PRIVILEGE:
217                 *errstr = PKGCMD_ERR_INVALID_PRIVILEGE_STR;
218                 break;
219         case PKGCMD_ERR_MENU_ICON_NOT_FOUND:
220                 *errstr = PKGCMD_ERR_MENU_ICON_NOT_FOUND_STR;
221                 break;
222         case PKGCMD_ERR_FATAL_ERROR:
223                 *errstr = PKGCMD_ERR_FATAL_ERROR_STR;
224                 break;
225         case PKGCMD_ERR_OUT_OF_STORAGE:
226                 *errstr = PKGCMD_ERR_OUT_OF_STORAGE_STR;
227                 break;
228         case PKGCMD_ERR_OUT_OF_MEMORY:
229                 *errstr = PKGCMD_ERR_OUT_OF_MEMORY_STR;
230                 break;
231         case PKGCMD_ERR_ARGUMENT_INVALID:
232                 *errstr = PKGCMD_ERR_ARGUMENT_INVALID_STR;
233                 break;
234         default:
235                 *errstr = PKGCMD_ERR_UNKNOWN_STR;
236                 break;
237         }
238 }
239
240 static int __return_cb(int req_id, const char *pkg_type,
241                        const char *pkgid, const char *key, const char *val,
242                        const void *pmsg, void *priv_data)
243 {
244         if (strncmp(key, "error", strlen("error")) == 0) {
245                 int ret_val;
246                 char *errstr = NULL;
247
248                 ret_val = atoi(val);
249                 __error_no_to_string(ret_val, &errstr);
250                 data.result = ret_val;
251
252                 printf("__return_cb req_id[%d] pkg_type[%s] pkgid[%s] key[%s] val[%d] error_message[%s]\n",
253                                    req_id, pkg_type, pkgid, key, ret_val, errstr);
254         } else
255                 printf("__return_cb req_id[%d] pkg_type[%s] "
256                        "pkgid[%s] key[%s] val[%s]\n",
257                        req_id, pkg_type, pkgid, key, val);
258
259         if (strncmp(key, "end", strlen("end")) == 0) {
260                 if ((strncmp(val, "fail", strlen("fail")) == 0) && data.result == 0){
261                         data.result = PKGCMD_ERR_FATAL_ERROR;
262                 }
263                 g_main_loop_quit(main_loop);
264         }
265
266         return 0;
267 }
268
269 static int __pkgcmd_read_proc(const char *path, char *buf, int size)
270 {
271         int fd;
272         int ret;
273         if (buf == NULL || path == NULL)
274                 return -1;
275         fd = open(path, O_RDONLY);
276         if (fd < 0)
277                 return -1;
278         ret = read(fd, buf, size - 1);
279         if (ret <= 0) {
280                 close(fd);
281                 return -1;
282         } else
283                 buf[ret] = 0;
284         close(fd);
285         return ret;
286 }
287
288 static int __pkgcmd_find_pid_by_cmdline(const char *dname,
289                         const char *cmdline, const char *apppath)
290 {
291         int pid = 0;
292
293         if (strcmp(cmdline, apppath) == 0) {
294                 pid = atoi(dname);
295                 if (pid != getpgid(pid))
296                         pid = 0;
297         }
298         return pid;
299 }
300
301 static int __pkgcmd_proc_iter_kill_cmdline(const char *apppath, int option)
302 {
303         DIR *dp;
304         struct dirent *dentry;
305         int pid;
306         int ret;
307         char buf[1024] = {'\0'};
308         int pgid;
309
310         dp = opendir("/proc");
311         if (dp == NULL) {
312                 return -1;
313         }
314
315         while ((dentry = readdir(dp)) != NULL) {
316                 if (!isdigit(dentry->d_name[0]))
317                         continue;
318
319                 snprintf(buf, sizeof(buf), "/proc/%s/cmdline", dentry->d_name);
320                 ret = __pkgcmd_read_proc(buf, buf, sizeof(buf));
321                 if (ret <= 0)
322                         continue;
323
324                 pid = __pkgcmd_find_pid_by_cmdline(dentry->d_name, buf, apppath);
325                 if (pid > 0) {
326                         if (option == 0) {
327                                 closedir(dp);
328                                 return pid;
329                         }
330                         pgid = getpgid(pid);
331                         if (pgid <= 1) {
332                                 closedir(dp);
333                                 return -1;
334                         }
335                         if (killpg(pgid, SIGKILL) < 0) {
336                                 closedir(dp);
337                                 return -1;
338                         }
339                         closedir(dp);
340                         return pid;
341                 }
342         }
343         closedir(dp);
344         return 0;
345 }
346
347 static int __app_list_cb(const pkgmgr_appinfo_h handle, void *user_data)
348 {
349         char *exec = NULL;
350         char *appid = NULL;
351         int ret = 0;
352         int pid = -1;
353         if (handle == NULL) {
354                 printf("appinfo handle is NULL\n");
355                 return -1;
356         }
357         ret = pkgmgr_appinfo_get_exec(handle, &exec);
358         if (ret) {
359                 printf("Failed to get app exec path\n");
360                 return -1;
361         }
362         ret = pkgmgr_appinfo_get_appid(handle, &appid);
363         if (ret) {
364                 printf("Failed to get appid\n");
365                 return -1;
366         }
367         /*option 0 to check and option 1 to kill*/
368         switch(data.request) {
369         case CHECKAPP_REQ:
370                 pid = __pkgcmd_proc_iter_kill_cmdline(exec, 0);
371                 if (pid) {
372                         printf("Appid: %s is Running\n", appid);
373                 } else {
374                         printf("Appid: %s is Not Running\n", appid);
375                 }
376                 break;
377         case KILLAPP_REQ:
378                 pid = __pkgcmd_proc_iter_kill_cmdline(exec, 1);
379                 if (pid > 0)
380                         printf("Appid: %s is Terminated\n", appid);
381                 break;
382         default:
383                 break;
384         }
385         return 0;
386 }
387
388 static int __convert_to_absolute_path(char *path)
389 {
390         char abs[PKG_NAME_STRING_LEN_MAX] = {'\0'};
391         char temp[PKG_NAME_STRING_LEN_MAX] = {'\0'};
392         char *ptr = NULL;
393         if (path == NULL) {
394                 printf("path is NULL\n");
395                 return -1;
396         }
397         strncpy(temp, path, PKG_NAME_STRING_LEN_MAX - 1);
398         if (strchr(path, '/') == NULL) {
399                 getcwd(abs, PKG_NAME_STRING_LEN_MAX - 1);
400                 if (abs[0] == '\0') {
401                         printf("getcwd() failed\n");
402                         return -1;
403                 }
404                 memset(data.pkg_path, '\0', PKG_NAME_STRING_LEN_MAX);
405                 snprintf(data.pkg_path, PKG_NAME_STRING_LEN_MAX - 1, "%s/%s", abs, temp);
406                 return 0;
407         }
408         if (strncmp(path, "./", 2) == 0) {
409                 ptr = temp;
410                 getcwd(abs, PKG_NAME_STRING_LEN_MAX - 1);
411                 if (abs[0] == '\0') {
412                         printf("getcwd() failed\n");
413                         return -1;
414                 }
415                 ptr = ptr + 2;
416                 memset(data.pkg_path, '\0', PKG_NAME_STRING_LEN_MAX);
417                 snprintf(data.pkg_path, PKG_NAME_STRING_LEN_MAX - 1, "%s/%s", abs, ptr);
418                 return 0;
419         }
420         return 0;
421 }
422
423 static int __is_app_installed(char *pkgid)
424 {
425 #if 0
426         ail_appinfo_h handle;
427         ail_error_e ret;
428         char *str = NULL;
429         ret = ail_package_get_appinfo(pkgid, &handle);
430         if (ret != AIL_ERROR_OK) {
431                 return -1;
432         }
433         ret = ail_appinfo_get_str(handle, AIL_PROP_NAME_STR, &str);
434         if (ret != AIL_ERROR_OK) {
435                 return -1;
436         }
437         ret = ail_package_destroy_appinfo(handle);
438         if (ret != AIL_ERROR_OK) {
439                 return -1;
440         }
441 //#else
442         pkgmgr_pkginfo_h handle;
443         int ret = pkgmgr_pkginfo_get_pkginfo(pkgid, &handle);
444         if(ret < 0) {
445                 printf("package is not in pkgmgr_info DB\n");
446                 return -1;
447         } else
448                 pkgmgr_pkginfo_destroy_pkginfo(handle);
449 #endif
450
451         return 0;
452 }
453
454 static void __print_usage()
455 {
456         printf("\nPackage Manager Tool Version: %s\n\n", PKG_TOOL_VERSION);
457         printf("-i, --install           install the package\n");
458         printf("-u, --uninstall         uninstall the package\n");
459         printf("-r, --reinstall         reinstall the package\n");
460         printf("-c, --clear             clear user data\n");
461         printf("-m, --move              move package\n");
462         printf("-l, --list              display list of installed packages\n");
463         printf("-s, --show              show detail package info\n");
464         printf("-a, --app-path          show app installation path\n");
465         printf("-C, --check             check if applications belonging to a package are running or not\n");
466         printf("-k, --kill              terminate applications belonging to a package\n");
467         printf("-d, --descriptor        provide descriptor path\n");
468         printf("-p, --package-path      provide package path\n");
469         printf("-n, --package-name      provide package name\n");
470         printf("-t, --package-type      provide package type\n");
471         printf("-T, --move-type provide move type [0 : move to internal /1: move to external]\n");
472         printf("-q, --quiet             quiet mode operation\n");
473         printf("-h, --help              print this help\n\n");
474
475         printf("Usage: pkgcmd [options] (--quiet)\n");
476         printf("pkgcmd -i -t <pkg type> (-d <descriptor path>) -p <pkg path> (-q)\n");
477         printf("pkgcmd -u -t <pkg type> -n <pkgid> (-q)\n");
478         printf("pkgcmd -r -t <pkg type> -n <pkgid> \n");
479         printf("pkgcmd -l (-t <pkg type>) \n");
480         printf("pkgcmd -s -t <pkg type> -p <pkg path> (-q)\n");
481         printf("pkgcmd -s -t <pkg type> -n <pkg name> (-q)\n");
482         printf("pkgcmd -m -t <pkg type> -T <move type> -n <pkg name> (-q)\n\n");
483
484         printf("Example:\n");
485         printf("pkgcmd -u -t rpm -n org.tizen.calculator\n");
486         printf("pkgcmd -i -t rpm -p /mnt/nfs/org.tizen.calculator_0.1.2-95_armel.rpm\n");
487         printf("pkgcmd -r -t rpm -p org.tizen.calculator\n");
488         printf("pkgcmd -c -t rpm -n org.tizen.hello\n");
489         printf("pkgcmd -m -t rpm -T 1 -n org.tizen.hello\n");
490         printf("pkgcmd -C -t rpm -n org.tizen.hello\n");
491         printf("pkgcmd -k -t rpm -n org.tizen.hello\n");
492         printf("pkgcmd -a\n");
493         printf("pkgcmd -a -t rpm -n org.tizen.hello\n");
494         printf("pkgcmd -l\n");
495         printf("pkgcmd -l -t tpk\n");
496
497         exit(0);
498
499 }
500
501 static void __print_pkg_info(pkgmgr_info *pkg_info)
502 {
503         char *temp = NULL;
504
505         temp = pkgmgr_info_get_string(pkg_info, "pkg_type");
506         if (temp) {
507                 printf("pkg_type : %s\n", temp);
508                 free(temp);
509         }
510
511         temp = pkgmgr_info_get_string(pkg_info, "pkgid");
512         if (temp) {
513                 printf("pkgid : %s\n", temp);
514                 free(temp);
515         }
516
517         temp = pkgmgr_info_get_string(pkg_info, "version");
518         if (temp) {
519                 printf("version : %s\n", temp);
520                 free(temp);
521         }
522
523         temp = pkgmgr_info_get_string(pkg_info, "pkg_vendor");
524         if (temp) {
525                 printf("pkg_vendor : %s\n", temp);
526                 free(temp);
527         }
528
529         temp = pkgmgr_info_get_string(pkg_info, "pkg_description");
530         if (temp) {
531                 printf("pkg_description : %s\n", temp);
532                 free(temp);
533         }
534
535         temp = pkgmgr_info_get_string(pkg_info, "pkg_mimetype");
536         if (temp) {
537                 printf("pkg_mimetype : %s\n", temp);
538                 free(temp);
539         }
540
541         temp = pkgmgr_info_get_string(pkg_info, "pkg_installed_path_package");
542         if (temp) {
543                 printf("pkg_installed_path_package : %s\n", temp);
544                 free(temp);
545         }
546
547         temp =
548             pkgmgr_info_get_string(pkg_info, "pkg_installed_path_descriptor");
549         if (temp) {
550                 printf("pkg_installed_path_descriptor : %s\n", temp);
551                 free(temp);
552         }
553
554         temp = pkgmgr_info_get_string(pkg_info, "category");
555         if (temp) {
556                 printf("category : %s\n", temp);
557                 free(temp);
558         }
559
560         temp = pkgmgr_info_get_string(pkg_info, "min_platform_version");
561         if (temp) {
562                 printf("min_platform_version : %s\n", temp);
563                 free(temp);
564         }
565
566         temp = pkgmgr_info_get_string(pkg_info, "visible");
567         if (temp) {
568                 printf("visible : %s\n", temp);
569                 free(temp);
570         }
571
572         temp = pkgmgr_info_get_string(pkg_info, "removable");
573         if (temp) {
574                 printf("removable : %s\n", temp);
575                 free(temp);
576         }
577
578         temp = pkgmgr_info_get_string(pkg_info, "installed_size");
579         if (temp) {
580                 printf("installed_size : %s\n", temp);
581                 free(temp);
582         }
583
584         temp = pkgmgr_info_get_string(pkg_info, "installed_time");
585         if (temp) {
586                 printf("installed_time : %s\n", temp);
587                 free(temp);
588         }
589
590         temp = pkgmgr_info_get_string(pkg_info, "data_size");
591         if (temp) {
592                 printf("data_size : %s\n", temp);
593                 free(temp);
594         }
595
596         temp = pkgmgr_info_get_string(pkg_info, "optional_id");
597         if (temp) {
598                 printf("optional_id : %s\n", temp);
599                 free(temp);
600         }
601 }
602
603 static int __pkgmgr_list_cb (const pkgmgr_pkginfo_h handle, void *user_data)
604 {
605         int ret = -1;
606         char *pkgid = NULL;
607         char *pkg_type = NULL;
608         char *pkg_version = NULL;
609         char *pkg_label = NULL;
610
611         ret = pkgmgr_pkginfo_get_pkgid(handle, &pkgid);
612         if (ret == -1) {
613                 printf("Failed to get pkgmgr_pkginfo_get_pkgid\n");
614                 return ret;
615         }
616         ret = pkgmgr_pkginfo_get_type(handle, &pkg_type);
617         if (ret == -1) {
618                 printf("Failed to get pkgmgr_pkginfo_get_type\n");
619                 return ret;
620         }
621         ret = pkgmgr_pkginfo_get_version(handle, &pkg_version);
622         if (ret == -1) {
623                 printf("Failed to get pkgmgr_pkginfo_get_version\n");
624                 return ret;
625         }
626         ret = pkgmgr_pkginfo_get_label(handle, &pkg_label);
627         if (ret == -1) {
628                 printf("Failed to get pkgmgr_pkginfo_get_label\n");
629                 return ret;
630         }
631
632         printf("pkg_type [%s]\tpkgid [%s]\tname [%s]\tversion [%s]\n", pkg_type, pkgid, pkg_label, pkg_version);
633
634         return ret;
635 }
636
637 static int __process_request()
638 {
639         int ret = -1;
640         int mode = PM_DEFAULT;
641         pkgmgr_client *pc = NULL;
642         char buf[1024] = {'\0'};
643         switch (data.request) {
644         case INSTALL_REQ:
645                 if (data.pkg_type[0] == '\0' || data.pkg_path[0] == '\0') {
646                         printf("Please provide the arguments.\n");
647                         printf("use -h option to see usage\n");
648                         data.result = PKGCMD_ERR_ARGUMENT_INVALID;
649                         break;
650                 }
651                 g_type_init();
652                 main_loop = g_main_loop_new(NULL, FALSE);
653                 pc = pkgmgr_client_new(PC_REQUEST);
654                 if (pc == NULL) {
655                         printf("PkgMgr Client Creation Failed\n");
656                         data.result = PKGCMD_ERR_FATAL_ERROR;
657                         break;
658                 }
659                 if (data.quiet == 0)
660                         mode = PM_DEFAULT;
661                 else
662                         mode = PM_QUIET;
663                 if (data.des_path[0] == '\0')
664                         ret =
665                             pkgmgr_client_install(pc, data.pkg_type, NULL,
666                                                   data.pkg_path, NULL, mode,
667                                                   __return_cb, pc);
668                 else
669                         ret =
670                             pkgmgr_client_install(pc, data.pkg_type,
671                                                   data.des_path, data.pkg_path,
672                                                   NULL, mode, __return_cb, pc);
673                 if (ret < 0){
674                         data.result = PKGCMD_ERR_FATAL_ERROR;
675                         if (access(data.pkg_path, F_OK) != 0)
676                                 data.result = PKGCMD_ERR_PACKAGE_NOT_FOUND;
677                         break;
678                 }
679                 g_main_loop_run(main_loop);
680                 ret = data.result;
681                 break;
682
683         case UNINSTALL_REQ:
684                 if (data.pkg_type[0] == '\0' || data.pkgid[0] == '\0') {
685                         printf("Please provide the arguments.\n");
686                         printf("use -h option to see usage\n");
687                         data.result = PKGCMD_ERR_ARGUMENT_INVALID;
688                         break;
689                 }
690                 g_type_init();
691                 main_loop = g_main_loop_new(NULL, FALSE);
692                 pc = pkgmgr_client_new(PC_REQUEST);
693                 if (pc == NULL) {
694                         printf("PkgMgr Client Creation Failed\n");
695                         data.result = PKGCMD_ERR_FATAL_ERROR;
696                         break;
697                 }
698                 if (data.quiet == 0)
699                         mode = PM_DEFAULT;
700                 else
701                         mode = PM_QUIET;
702
703                 ret = __is_app_installed(data.pkgid);
704                 if (ret == -1) {
705                         printf("package is not installed\n");
706                         break;
707                 }
708
709                 ret =
710                     pkgmgr_client_uninstall(pc, data.pkg_type, data.pkgid,
711                                             mode, __return_cb, NULL);
712                 if (ret < 0){
713                         data.result = PKGCMD_ERR_FATAL_ERROR;
714                         if (access(data.pkg_path, F_OK) != 0)
715                                 data.result = PKGCMD_ERR_PACKAGE_NOT_FOUND;
716                         break;
717                 }
718                 g_main_loop_run(main_loop);
719                 ret = data.result;
720                 break;
721
722         case REINSTALL_REQ:
723                 if (data.pkg_type[0] == '\0' || data.pkgid[0] == '\0') {
724                         printf("Please provide the arguments.\n");
725                         printf("use -h option to see usage\n");
726                         data.result = PKGCMD_ERR_ARGUMENT_INVALID;
727                         break;
728                 }
729                 g_type_init();
730                 main_loop = g_main_loop_new(NULL, FALSE);
731                 pc = pkgmgr_client_new(PC_REQUEST);
732                 if (pc == NULL) {
733                         printf("PkgMgr Client Creation Failed\n");
734                         data.result = PKGCMD_ERR_FATAL_ERROR;
735                         break;
736                 }
737
738                 mode = PM_QUIET;
739                 ret = pkgmgr_client_reinstall(pc, data.pkg_type, data.pkgid, NULL, mode, __return_cb, pc);
740                 if (ret < 0){
741                         data.result = PKGCMD_ERR_FATAL_ERROR;
742                         if (access(data.pkg_path, F_OK) != 0)
743                                 data.result = PKGCMD_ERR_PACKAGE_NOT_FOUND;
744                         break;
745                 }
746                 g_main_loop_run(main_loop);
747                 ret = data.result;
748                 break;
749
750         case CLEAR_REQ:
751                 if (data.pkg_type[0] == '\0' || data.pkgid[0] == '\0') {
752                         printf("Please provide the arguments.\n");
753                         printf("use -h option to see usage\n");
754                         ret = -1;
755                         break;
756                 }
757
758                 pc = pkgmgr_client_new(PC_REQUEST);
759                 if (pc == NULL) {
760                         printf("PkgMgr Client Creation Failed\n");
761                         ret = -1;
762                         break;
763                 }
764                 if (data.quiet == 0)
765                         mode = PM_DEFAULT;
766                 else
767                         mode = PM_QUIET;
768                 ret = __is_app_installed(data.pkgid);
769                 if (ret == -1) {
770                         printf("package is not installed\n");
771                         break;
772                 }
773                 ret = pkgmgr_client_clear_user_data(pc, data.pkg_type,
774                                                     data.pkgid, mode);
775                 if (ret < 0)
776                         break;
777                 ret = data.result;
778                 break;
779
780         case ACTIVATE_REQ:
781                 if (data.pkg_type[0] == '\0' || data.pkgid[0] == '\0') {
782                         printf("Please provide the arguments.\n");
783                         printf("use -h option to see usage\n");
784                         ret = -1;
785                         break;
786                 }
787
788                 pc = pkgmgr_client_new(PC_REQUEST);
789                 if (pc == NULL) {
790                         printf("PkgMgr Client Creation Failed\n");
791                         ret = -1;
792                         break;
793                 }
794
795                 if ( strcmp(data.pkg_type, "app") == 0 ) {
796                         if (strlen(data.label) == 0) {
797                                 ret = pkgmgr_client_activate_app(pc, data.pkgid);
798                                 if (ret < 0)
799                                         break;
800                         } else {
801                                 printf("label [%s]\n", data.label);
802                                 char *largv[3] = {NULL, };
803                                 largv[0] = "-l";
804                                 largv[1] = data.label;
805                                 ret = pkgmgr_client_activate_appv(pc, data.pkgid, largv);
806                                 if (ret < 0)
807                                         break;
808                         }
809                 } else {
810                         ret = pkgmgr_client_activate(pc, data.pkg_type, data.pkgid);
811                         if (ret < 0)
812                                 break;
813                 }
814                 ret = data.result;
815
816                 break;
817
818
819         case DEACTIVATE_REQ:
820                 if (data.pkg_type[0] == '\0' || data.pkgid[0] == '\0') {
821                         printf("Please provide the arguments.\n");
822                         printf("use -h option to see usage\n");
823                         ret = -1;
824                         break;
825                 }
826
827                 pc = pkgmgr_client_new(PC_REQUEST);
828                 if (pc == NULL) {
829                         printf("PkgMgr Client Creation Failed\n");
830                         ret = -1;
831                         break;
832                 }
833
834                 if ( strcmp(data.pkg_type, "app") == 0 ) {
835                         ret = pkgmgr_client_deactivate_app(pc, data.pkgid);
836                         if (ret < 0)
837                                 break;
838                 } else {
839                         ret = pkgmgr_client_deactivate(pc, data.pkg_type, data.pkgid);
840                         if (ret < 0)
841                                 break;
842                 }
843                 ret = data.result;
844
845                 break;
846
847         case MOVE_REQ:
848                 if (data.pkg_type[0] == '\0' || data.pkgid[0] == '\0') {
849                         printf("Please provide the arguments.\n");
850                         printf("use -h option to see usage\n");
851                         ret = -1;
852                         break;
853                 }
854                 if (data.move_type < 0 || data.move_type > 1) {
855                         printf("Invalid move type...See usage\n");
856                         ret = -1;
857                         break;
858                 }
859                 pc = pkgmgr_client_new(PC_REQUEST);
860                 if (pc == NULL) {
861                         printf("PkgMgr Client Creation Failed\n");
862                         ret = -1;
863                         break;
864                 }
865                 if (data.quiet == 0)
866                         mode = PM_DEFAULT;
867                 else
868                         mode = PM_QUIET;
869                 ret = __is_app_installed(data.pkgid);
870                 if (ret == -1) {
871                         printf("package is not installed\n");
872                         break;
873                 }
874                 ret = pkgmgr_client_move(pc, data.pkg_type, data.pkgid,  data.move_type, mode);
875                 if (ret < 0)
876                         break;
877                 ret = data.result;
878                 break;
879
880         case APPPATH_REQ:
881                 if (data.pkg_type[0] == '\0' && data.pkgid[0] == '\0') {
882                         printf("Tizen Application Installation Path: %s\n", APP_INSTALLATION_PATH_RW);
883                         ret = 0;
884                         break;
885                 }
886                 if ((data.pkg_type[0] == '\0') || (data.pkgid[0] == '\0')) {
887                         printf("Use -h option to see usage\n");
888                         ret = -1;
889                         break;
890                 }
891                 if (strncmp(data.pkg_type, "rpm", PKG_TYPE_STRING_LEN_MAX - 1) == 0) {
892                         snprintf(buf, 1023, "%s/%s", APP_INSTALLATION_PATH_RW, data.pkgid);
893                         printf("Tizen Application Installation Path: %s\n", buf);
894                         ret = 0;
895                         break;
896                 } else if (strncmp(data.pkg_type, "wgt", PKG_TYPE_STRING_LEN_MAX - 1) == 0) {
897                         snprintf(buf, 1023, "%s/%s/res/wgt", APP_INSTALLATION_PATH_RW, data.pkgid);
898                         printf("Tizen Application Installation Path: %s\n", buf);
899                         ret = 0;
900                         break;
901                 } else if (strncmp(data.pkg_type, "tpk", PKG_TYPE_STRING_LEN_MAX - 1) == 0) {
902                         snprintf(buf, 1023, "%s/%s", APP_INSTALLATION_PATH_RW, data.pkgid);
903                         printf("Tizen Application Installation Path: %s\n", buf);
904                         ret = 0;
905                         break;
906                 } else {
907                         printf("Invalid package type.\n");
908                         printf("use -h option to see usage\n");
909                         ret = -1;
910                         break;
911                 }
912                 break;
913
914         case KILLAPP_REQ:
915         case CHECKAPP_REQ:
916                 if (data.pkg_type[0] == '\0' || data.pkgid[0] == '\0') {
917                         printf("Please provide the arguments.\n");
918                         printf("use -h option to see usage\n");
919                         ret = -1;
920                         break;
921                 }
922                 pkgmgr_pkginfo_h handle;
923                 ret = pkgmgr_pkginfo_get_pkginfo(data.pkgid, &handle);
924                 if (ret < 0) {
925                         printf("Failed to get handle\n");
926                         return -1;
927                 }
928                 ret = pkgmgr_appinfo_get_list(handle, PM_UI_APP, __app_list_cb, NULL);
929                 if (ret < 0) {
930                         printf("pkgmgr_appinfo_get_list() failed\n");
931                         pkgmgr_pkginfo_destroy_pkginfo(handle);
932                         return -1;
933                 }
934                 ret = pkgmgr_appinfo_get_list(handle, PM_SVC_APP, __app_list_cb, NULL);
935                 if (ret < 0) {
936                         printf("pkgmgr_appinfo_get_list() failed\n");
937                         pkgmgr_pkginfo_destroy_pkginfo(handle);
938                         return -1;
939                 }
940                 pkgmgr_pkginfo_destroy_pkginfo(handle);
941                 ret = 0;
942                 break;
943
944         case LIST_REQ:
945                 if (data.pkg_type[0] == '\0') {
946                         ret = pkgmgr_pkginfo_get_list(__pkgmgr_list_cb, NULL);
947                         if (ret == -1) {
948                                 printf("Failed to get package list\n");
949                                 break;
950                         }
951                         break;
952                 } else {
953                         pkgmgrinfo_pkginfo_filter_h handle;
954                         ret = pkgmgrinfo_pkginfo_filter_create(&handle);
955                         if (ret == -1) {
956                                 printf("Failed to get package filter handle\n");
957                                 break;
958                         }
959                         ret = pkgmgrinfo_pkginfo_filter_add_string(handle, PMINFO_PKGINFO_PROP_PACKAGE_TYPE, data.pkg_type);
960                         if (ret == -1) {
961                                 printf("Failed to add package type filter\n");
962                                 pkgmgrinfo_pkginfo_filter_destroy(handle);
963                                 break;
964                         }
965                         ret = pkgmgrinfo_pkginfo_filter_foreach_pkginfo(handle, __pkgmgr_list_cb, NULL);
966                         if (ret == -1) {
967                                 printf("Failed to get package filter list\n");
968                                 pkgmgrinfo_pkginfo_filter_destroy(handle);
969                                 break;
970                         }
971                         pkgmgrinfo_pkginfo_filter_destroy(handle);
972                         break;
973                 }
974
975         case SHOW_REQ:
976                 if (data.pkgid[0] != '\0') {
977                         pkgmgr_info *pkg_info =
978                             pkgmgr_info_new(data.pkg_type, data.pkgid);
979                         if (pkg_info == NULL) {
980                                 printf("Failed to get pkginfo handle\n");
981                                 ret = -1;
982                                 break;
983                         }
984                         __print_pkg_info(pkg_info);
985                         ret = pkgmgr_info_free(pkg_info);
986                         break;
987                 }
988                 if (data.pkg_path[0] != '\0') {
989                         pkgmgr_info *pkg_info =
990                             pkgmgr_info_new_from_file(data.pkg_type,
991                                                       data.pkg_path);
992                         if (pkg_info == NULL) {
993                                 printf("Failed to get pkginfo handle\n");
994                                 ret = -1;
995                                 break;
996                         }
997                         __print_pkg_info(pkg_info);
998                         ret = pkgmgr_info_free(pkg_info);
999                         break;
1000                 }
1001                 printf("Either pkgid or pkgpath should be supplied\n");
1002                 ret = -1;
1003                 break;
1004
1005         case HELP_REQ:
1006                 __print_usage();
1007                 ret = 0;
1008                 break;
1009
1010         default:
1011                 printf("Wrong Request\n");
1012                 ret = -1;
1013                 break;
1014         }
1015
1016         if (pc) {
1017                 pkgmgr_client_free(pc);
1018                 pc = NULL;
1019         }
1020         return ret;
1021 }
1022
1023 static int __is_authorized()
1024 {
1025         /* pkgcmd needs root or developer privileges.
1026            If launched via fork/exec, the launching program 
1027            must be running as root */
1028
1029         uid_t uid = getuid();
1030         if ((uid_t) 0 == uid || (uid_t) 5100 == uid)
1031                 return 1;
1032         else
1033                 return 0;
1034 }
1035
1036 int main(int argc, char *argv[])
1037 {
1038         optind = 1;
1039         int opt_idx = 0;
1040         int c = -1;
1041         int ret = -1;
1042         char *errstr = NULL;
1043         long starttime;
1044         long endtime;
1045         struct timeval tv;
1046
1047         if (!__is_authorized()) {
1048                 printf("You are not an authorized user!\n");
1049                 return PKGCMD_ERR_FATAL_ERROR;
1050         }
1051
1052         if (argc == 1)
1053                 __print_usage();
1054
1055         gettimeofday(&tv, NULL);
1056         starttime = tv.tv_sec * 1000l + tv.tv_usec / 1000l;
1057
1058         data.request = -1;
1059         memset(data.des_path, '\0', PKG_NAME_STRING_LEN_MAX);
1060         memset(data.pkg_path, '\0', PKG_NAME_STRING_LEN_MAX);
1061         memset(data.pkgid, '\0', PKG_NAME_STRING_LEN_MAX);
1062         memset(data.pkg_type, '\0', PKG_TYPE_STRING_LEN_MAX);
1063         memset(data.label, '\0', PKG_TYPE_STRING_LEN_MAX);
1064         data.quiet = 0;
1065         data.result = 0;
1066         data.move_type = -1;
1067         while (1) {
1068                 c = getopt_long(argc, argv, short_options, long_options,
1069                                 &opt_idx);
1070                 if (c == -1)
1071                         break;  /* Parse end */
1072                 switch (c) {
1073                 case 'i':       /* install */
1074                         data.request = INSTALL_REQ;
1075                         break;
1076
1077                 case 'u':       /* uninstall */
1078                         data.request = UNINSTALL_REQ;
1079                         break;
1080
1081                 case 'r':       /* reinstall */
1082                         data.request = REINSTALL_REQ;
1083                         break;
1084
1085                 case 'c':       /* clear */
1086                         data.request = CLEAR_REQ;
1087                         break;
1088
1089                 case 'm':       /* move */
1090                         data.request = MOVE_REQ;
1091                         break;
1092
1093                 case 'A':       /* activate */
1094                         data.request = ACTIVATE_REQ;
1095                         break;
1096
1097                 case 'D':       /* deactivate */
1098                         data.request = DEACTIVATE_REQ;
1099                         break;
1100
1101                 case 'L':       /* activate with Label */
1102                         data.request = ACTIVATE_REQ;
1103                         if (optarg)
1104                                 strncpy(data.label, optarg,
1105                                         PKG_NAME_STRING_LEN_MAX);
1106                         break;
1107
1108                 case 'a':       /* app installation path */
1109                         data.request = APPPATH_REQ;
1110                         break;
1111
1112                 case 'k':       /* Terminate applications of a package */
1113                         data.request = KILLAPP_REQ;
1114                         break;
1115
1116                 case 'C':       /* Check running status of applications of a package */
1117                         data.request = CHECKAPP_REQ;
1118                         break;
1119
1120                 case 'l':       /* list */
1121                         data.request = LIST_REQ;
1122                         break;
1123
1124                 case 's':       /* show */
1125                         data.request = SHOW_REQ;
1126                         break;
1127
1128                 case 'p':       /* package path */
1129                         if (optarg)
1130                                 strncpy(data.pkg_path, optarg,
1131                                         PKG_NAME_STRING_LEN_MAX);
1132                         ret = __convert_to_absolute_path(data.pkg_path);
1133                         if (ret == -1) {
1134                                 printf("conversion of relative path to absolute path failed\n");
1135                                 return -1;
1136                         }
1137                         printf("package path is %s\n", data.pkg_path);
1138                         break;
1139
1140                 case 'd':       /* descriptor path */
1141                         if (optarg)
1142                                 strncpy(data.des_path, optarg,
1143                                         PKG_NAME_STRING_LEN_MAX);
1144                         break;
1145
1146                 case 'n':       /* package name */
1147                         if (optarg)
1148                                 strncpy(data.pkgid, optarg,
1149                                         PKG_NAME_STRING_LEN_MAX);
1150                         break;
1151
1152                 case 't':       /* package type */
1153                         if (optarg)
1154                                 strncpy(data.pkg_type, optarg,
1155                                         PKG_TYPE_STRING_LEN_MAX);
1156                         break;
1157
1158                 case 'T':       /* move type */
1159                         data.move_type = atoi(optarg);
1160                         break;
1161
1162                 case 'h':       /* help */
1163                         data.request = HELP_REQ;
1164                         break;
1165
1166                 case 'q':       /* quiet mode */
1167                         data.quiet = 1;
1168                         break;
1169
1170                         /* Otherwise */
1171                 case '?':       /* Not an option */
1172                         __print_usage();
1173                         break;
1174
1175                 case ':':       /* */
1176                         break;
1177
1178                 default:
1179                         break;
1180
1181                 }
1182         }
1183         ret = __process_request();
1184         if (ret == -1)
1185                 data.result = PKGCMD_ERR_ARGUMENT_INVALID;
1186
1187         if (ret != 0) {
1188                 __error_no_to_string(data.result, &errstr);
1189                 printf("processing result : %s [%d] failed\n", errstr, data.result);
1190         } else {
1191                 if (data.request == INSTALL_REQ)
1192                         sleep(2);
1193         }
1194
1195
1196         gettimeofday(&tv, NULL);
1197         endtime = tv.tv_sec * 1000l + tv.tv_usec / 1000l;
1198         printf("spend time for pkgcmd is [%d]ms\n", (int)(endtime - starttime));
1199
1200         return data.result;
1201 }