Upload Tizen2.0 beta source
[framework/appfw/slp-pkgmgr.git] / tool / pkg_cmd.c
1 /*
2  * slp-pkgmgr
3  *
4  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: Jayoun Lee <airjany@samsung.com>, Sewook Park <sewook7.park@samsung.com>,
7  * Jaeho Lee <jaeho81.lee@samsung.com>, Shobhit Srivastava <shobhit.s@samsung.com>
8  *
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  * http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  *
21  */
22
23 #define _GNU_SOURCE
24
25 #include <stdio.h>
26 #include <string.h>
27 #include <stdlib.h>
28 #include <unistd.h>
29 #include <getopt.h>
30 #include <sys/types.h>
31 #include <glib.h>
32 #include <ail.h>
33 #include <glib-object.h>
34 #include "package-manager.h"
35 #include "package-manager-types.h"
36
37 #define PKG_TOOL_VERSION        "0.1"
38
39 static int __process_request();
40 static void __print_usage();
41 static int __is_authorized();
42 static int __is_app_installed(char *pkgname);
43 static void __print_pkg_info(pkgmgr_info * pkg_info);
44 static int __iter_fn(const char *pkg_type, const char *pkg_name,
45                      const char *version, void *data);
46 static int __return_cb(int req_id, const char *pkg_type, const char *pkg_name,
47                        const char *key, const char *val, const void *pmsg,
48                        void *data);
49 static int __convert_to_absolute_path(char *path);
50
51 /* Supported options */
52 const char *short_options = "iucADlsd:p:t:n:qh";
53 const struct option long_options[] = {
54         {"install", 0, NULL, 'i'},
55         {"uninstall", 0, NULL, 'u'},
56         {"clear", 0, NULL, 'c'},
57         {"activate", 0, NULL, 'A'},
58         {"deactivate", 0, NULL, 'D'},
59         {"list", 0, NULL, 'l'},
60         {"show", 0, NULL, 's'},
61         {"descriptor", 1, NULL, 'd'},
62         {"package-path", 1, NULL, 'p'},
63         {"package-type", 1, NULL, 't'},
64         {"package-name", 1, NULL, 'n'},
65         {"quiet", 0, NULL, 'q'},
66         {"help", 0, NULL, 'h'},
67         {0, 0, 0, 0}            /* sentinel */
68 };
69
70 enum pm_tool_request_e {
71         INSTALL_REQ = 1,
72         UNINSTALL_REQ,
73         CLEAR_REQ,
74         ACTIVATE_REQ,
75         DEACTIVATE_REQ,
76         LIST_REQ,
77         SHOW_REQ,
78         HELP_REQ
79 };
80 typedef enum pm_tool_request_e req_type;
81
82 struct pm_tool_args_t {
83         req_type request;
84         char pkg_path[PKG_NAME_STRING_LEN_MAX];
85         char pkg_type[PKG_TYPE_STRING_LEN_MAX];
86         char pkg_name[PKG_NAME_STRING_LEN_MAX];
87         char des_path[PKG_NAME_STRING_LEN_MAX];
88         int quiet;
89         int result;
90 };
91 typedef struct pm_tool_args_t pm_tool_args;
92 pm_tool_args data;
93
94 static GMainLoop *main_loop = NULL;
95
96 static int __iter_fn(const char *pkg_type, const char *pkg_name,
97                      const char *version, void *data)
98 {
99         printf("pkg_type [%s]\tpkg_name [%s]\tversion [%s]\n", pkg_type,
100                pkg_name, version);
101         return 0;
102 }
103
104 static int __return_cb(int req_id, const char *pkg_type,
105                        const char *pkg_name, const char *key, const char *val,
106                        const void *pmsg, void *priv_data)
107 {
108         printf("__return_cb req_id[%d] pkg_type[%s] "
109                "pkg_name[%s] key[%s] val[%s]\n",
110                req_id, pkg_type, pkg_name, key, val);
111
112         if (strncmp(key, "end", strlen("end")) == 0) {
113                 if (strncasecmp(val, "ok", strlen("ok")) != 0)
114                         data.result = EXIT_FAILURE;     //error_code
115
116                 g_main_loop_quit(main_loop);
117         }
118
119         return 0;
120 }
121
122 static int __convert_to_absolute_path(char *path)
123 {
124         char abs[PKG_NAME_STRING_LEN_MAX] = {'\0'};
125         char temp[PKG_NAME_STRING_LEN_MAX] = {'\0'};
126         char *ptr = NULL;
127         if (path == NULL) {
128                 printf("path is NULL\n");
129                 return -1;
130         }
131         strncpy(temp, path, PKG_NAME_STRING_LEN_MAX - 1);
132         if (strchr(path, '/') == NULL) {
133                 getcwd(abs, PKG_NAME_STRING_LEN_MAX - 1);
134                 if (abs == NULL) {
135                         printf("getcwd() failed\n");
136                         return -1;
137                 }
138                 memset(data.pkg_path, '\0', PKG_NAME_STRING_LEN_MAX);
139                 snprintf(data.pkg_path, PKG_NAME_STRING_LEN_MAX - 1, "%s/%s", abs, temp);
140                 return 0;
141         }
142         if (strncmp(path, "./", 2) == 0) {
143                 ptr = temp;
144                 getcwd(abs, PKG_NAME_STRING_LEN_MAX - 1);
145                 if (abs == NULL) {
146                         printf("getcwd() failed\n");
147                         return -1;
148                 }
149                 ptr = ptr + 2;
150                 memset(data.pkg_path, '\0', PKG_NAME_STRING_LEN_MAX);
151                 snprintf(data.pkg_path, PKG_NAME_STRING_LEN_MAX - 1, "%s/%s", abs, ptr);
152                 return 0;
153         }
154         return 0;
155 }
156
157 static int __is_app_installed(char *pkgname)
158 {
159         ail_appinfo_h handle;
160         ail_error_e ret;
161         char *str = NULL;
162         ret = ail_package_get_appinfo(pkgname, &handle);
163         if (ret != AIL_ERROR_OK) {
164                 return -1;
165         }
166         ret = ail_appinfo_get_str(handle, AIL_PROP_NAME_STR, &str);
167         if (ret != AIL_ERROR_OK) {
168                 return -1;
169         }
170         ret = ail_package_destroy_appinfo(handle);
171         if (ret != AIL_ERROR_OK) {
172                 return -1;
173         }
174
175         return 0;
176 }
177
178 static void __print_usage()
179 {
180         printf("\nPackage Manager Tool Version: %s\n\n", PKG_TOOL_VERSION);
181         printf("-i, --install           install the package\n");
182         printf("-u, --uninstall         uninstall the package\n");
183         printf("-c, --clear             clear user data\n");
184         printf("-l, --list              display list of installed packages\n");
185         printf("-s, --show              show detail package info\n");
186         printf("-d, --descriptor        provide descriptor path\n");
187         printf("-p, --package-path      provide package path\n");
188         printf("-n, --package-name      provide package name\n");
189         printf("-t, --package-type      provide package type\n");
190         printf("-q, --quiet             quiet mode operation\n");
191         printf("-h, --help              print this help\n\n");
192         printf("Usage: pkgcmd [options] (--quiet)\n");
193         printf
194             ("pkgcmd -i -t <pkg type> (-d <descriptor path>) -p <pkg path> (-q)\n");
195         printf("pkgcmd -u -t <pkg type> -n <pkg name> (-q)\n");
196         printf("pkgcmd -l \n");
197         printf("pkgcmd -s -t <pkg type> -p <pkg path> (-q)\n");
198         printf("pkgcmd -s -t <pkg type> -n <pkg name> (-q)\n\n");
199         printf("Example:\n");
200         printf("pkgcmd -u -t deb -n org.tizen.calculator\n");
201         printf
202             ("pkgcmd -i -t deb -p /mnt/nfs/org.tizen.calculator_0.1.2-95_armel.deb\n");
203         printf("pkgcmd -c -t deb -n org.tizen.hello\n");
204         exit(0);
205
206 }
207
208 static void __print_pkg_info(pkgmgr_info *pkg_info)
209 {
210         char *temp = NULL;
211
212         temp = pkgmgr_info_get_string(pkg_info, "pkg_type");
213         if (temp) {
214                 printf("pkg_type : %s\n", temp);
215                 free(temp);
216         }
217
218         temp = pkgmgr_info_get_string(pkg_info, "pkg_name");
219         if (temp) {
220                 printf("pkg_name : %s\n", temp);
221                 free(temp);
222         }
223
224         temp = pkgmgr_info_get_string(pkg_info, "version");
225         if (temp) {
226                 printf("version : %s\n", temp);
227                 free(temp);
228         }
229
230         temp = pkgmgr_info_get_string(pkg_info, "pkg_vendor");
231         if (temp) {
232                 printf("pkg_vendor : %s\n", temp);
233                 free(temp);
234         }
235
236         temp = pkgmgr_info_get_string(pkg_info, "pkg_description");
237         if (temp) {
238                 printf("pkg_description : %s\n", temp);
239                 free(temp);
240         }
241
242         temp = pkgmgr_info_get_string(pkg_info, "pkg_mimetype");
243         if (temp) {
244                 printf("pkg_mimetype : %s\n", temp);
245                 free(temp);
246         }
247
248         temp = pkgmgr_info_get_string(pkg_info, "pkg_installed_path_package");
249         if (temp) {
250                 printf("pkg_installed_path_package : %s\n", temp);
251                 free(temp);
252         }
253
254         temp =
255             pkgmgr_info_get_string(pkg_info, "pkg_installed_path_descriptor");
256         if (temp) {
257                 printf("pkg_installed_path_descriptor : %s\n", temp);
258                 free(temp);
259         }
260
261         temp = pkgmgr_info_get_string(pkg_info, "category");
262         if (temp) {
263                 printf("category : %s\n", temp);
264                 free(temp);
265         }
266
267         temp = pkgmgr_info_get_string(pkg_info, "min_platform_version");
268         if (temp) {
269                 printf("min_platform_version : %s\n", temp);
270                 free(temp);
271         }
272
273         temp = pkgmgr_info_get_string(pkg_info, "visible");
274         if (temp) {
275                 printf("visible : %s\n", temp);
276                 free(temp);
277         }
278
279         temp = pkgmgr_info_get_string(pkg_info, "removable");
280         if (temp) {
281                 printf("removable : %s\n", temp);
282                 free(temp);
283         }
284
285         temp = pkgmgr_info_get_string(pkg_info, "installed_size");
286         if (temp) {
287                 printf("installed_size : %s\n", temp);
288                 free(temp);
289         }
290
291         temp = pkgmgr_info_get_string(pkg_info, "installed_time");
292         if (temp) {
293                 printf("installed_time : %s\n", temp);
294                 free(temp);
295         }
296
297         temp = pkgmgr_info_get_string(pkg_info, "data_size");
298         if (temp) {
299                 printf("data_size : %s\n", temp);
300                 free(temp);
301         }
302
303         temp = pkgmgr_info_get_string(pkg_info, "optional_id");
304         if (temp) {
305                 printf("optional_id : %s\n", temp);
306                 free(temp);
307         }
308 }
309
310 static int __process_request()
311 {
312         int ret = -1;
313         int mode = PM_DEFAULT;
314         pkgmgr_client *pc = NULL;
315         switch (data.request) {
316         case INSTALL_REQ:
317                 if (data.pkg_type[0] == '\0' || data.pkg_path[0] == '\0') {
318                         printf("Please provide the arguments.\n");
319                         printf("use -h option to see usage\n");
320                         ret = -1;
321                         break;
322                 }
323                 g_type_init();
324                 main_loop = g_main_loop_new(NULL, FALSE);
325                 pc = pkgmgr_client_new(PC_REQUEST);
326                 if (pc == NULL) {
327                         printf("PkgMgr Client Creation Failed\n");
328                         ret = -1;
329                         break;
330                 }
331                 if (data.quiet == 0)
332                         mode = PM_DEFAULT;
333                 else
334                         mode = PM_QUIET;
335                 if (data.des_path[0] == '\0')
336                         ret =
337                             pkgmgr_client_install(pc, data.pkg_type, NULL,
338                                                   data.pkg_path, NULL, mode,
339                                                   __return_cb, pc);
340                 else
341                         ret =
342                             pkgmgr_client_install(pc, data.pkg_type,
343                                                   data.des_path, data.pkg_path,
344                                                   NULL, mode, __return_cb, pc);
345                 if (ret < 0)
346                         break;
347                 g_main_loop_run(main_loop);
348                 ret = data.result;
349                 break;
350
351         case UNINSTALL_REQ:
352                 if (data.pkg_type[0] == '\0' || data.pkg_name[0] == '\0') {
353                         printf("Please provide the arguments.\n");
354                         printf("use -h option to see usage\n");
355                         ret = -1;
356                         break;
357                 }
358                 g_type_init();
359                 main_loop = g_main_loop_new(NULL, FALSE);
360                 pc = pkgmgr_client_new(PC_REQUEST);
361                 if (pc == NULL) {
362                         printf("PkgMgr Client Creation Failed\n");
363                         ret = -1;
364                         break;
365                 }
366                 if (data.quiet == 0)
367                         mode = PM_DEFAULT;
368                 else
369                         mode = PM_QUIET;
370 #if 0
371                 ret = __is_app_installed(data.pkg_name);
372                 if (ret == -1) {
373                         printf("package is not installed\n");
374                         break;
375                 }
376 #else
377                 pkgmgr_pkginfo_h handle;
378                 ret = pkgmgr_get_pkginfo(data.pkg_name, &handle);
379                 if(ret < 0) {
380                         printf("package is not in pkgmgr_info DB\n");
381                 } else
382                         pkgmgr_destroy_pkginfo(handle);
383 #endif
384                 ret =
385                     pkgmgr_client_uninstall(pc, data.pkg_type, data.pkg_name,
386                                             mode, __return_cb, NULL);
387                 if (ret < 0)
388                         break;
389                 g_main_loop_run(main_loop);
390                 ret = data.result;
391                 break;
392
393         case CLEAR_REQ:
394                 if (data.pkg_type[0] == '\0' || data.pkg_name[0] == '\0') {
395                         printf("Please provide the arguments.\n");
396                         printf("use -h option to see usage\n");
397                         ret = -1;
398                         break;
399                 }
400
401                 pc = pkgmgr_client_new(PC_REQUEST);
402                 if (pc == NULL) {
403                         printf("PkgMgr Client Creation Failed\n");
404                         ret = -1;
405                         break;
406                 }
407                 if (data.quiet == 0)
408                         mode = PM_DEFAULT;
409                 else
410                         mode = PM_QUIET;
411                 ret = __is_app_installed(data.pkg_name);
412                 if (ret == -1) {
413                         printf("package is not installed\n");
414                         break;
415                 }
416                 ret = pkgmgr_client_clear_user_data(pc, data.pkg_type,
417                                                     data.pkg_name, mode);
418                 if (ret < 0)
419                         break;
420                 ret = data.result;
421                 break;
422
423         case ACTIVATE_REQ:
424                 if (data.pkg_type[0] == '\0' || data.pkg_name[0] == '\0') {
425                         printf("Please provide the arguments.\n");
426                         printf("use -h option to see usage\n");
427                         ret = -1;
428                         break;
429                 }
430
431                 pc = pkgmgr_client_new(PC_REQUEST);
432                 if (pc == NULL) {
433                         printf("PkgMgr Client Creation Failed\n");
434                         ret = -1;
435                         break;
436                 }
437
438                 ret = pkgmgr_client_activate(pc, data.pkg_type, data.pkg_name);
439                 if (ret < 0)
440                         break;
441                 ret = data.result;
442
443                 break;
444
445
446         case DEACTIVATE_REQ:
447                 if (data.pkg_type[0] == '\0' || data.pkg_name[0] == '\0') {
448                         printf("Please provide the arguments.\n");
449                         printf("use -h option to see usage\n");
450                         ret = -1;
451                         break;
452                 }
453
454                 pc = pkgmgr_client_new(PC_REQUEST);
455                 if (pc == NULL) {
456                         printf("PkgMgr Client Creation Failed\n");
457                         ret = -1;
458                         break;
459                 }
460
461                 ret = pkgmgr_client_deactivate(pc, data.pkg_type, data.pkg_name);
462                 if (ret < 0)
463                         break;
464                 ret = data.result;
465
466                 break;
467
468         case LIST_REQ:
469                 ret = pkgmgr_get_pkg_list(__iter_fn, NULL);
470                 break;
471
472         case SHOW_REQ:
473                 if (data.pkg_name[0] != '\0') {
474                         pkgmgr_info *pkg_info =
475                             pkgmgr_info_new(data.pkg_type, data.pkg_name);
476                         if (pkg_info == NULL) {
477                                 printf("Failed to get pkginfo handle\n");
478                                 ret = -1;
479                                 break;
480                         }
481                         __print_pkg_info(pkg_info);
482                         ret = pkgmgr_info_free(pkg_info);
483                         break;
484                 }
485                 if (data.pkg_path[0] != '\0') {
486                         pkgmgr_info *pkg_info =
487                             pkgmgr_info_new_from_file(data.pkg_type,
488                                                       data.pkg_path);
489                         if (pkg_info == NULL) {
490                                 printf("Failed to get pkginfo handle\n");
491                                 ret = -1;
492                                 break;
493                         }
494                         __print_pkg_info(pkg_info);
495                         ret = pkgmgr_info_free(pkg_info);
496                         break;
497                 }
498                 printf("Either pkgname or pkgpath should be supplied\n");
499                 ret = -1;
500                 break;
501
502         case HELP_REQ:
503                 __print_usage();
504                 ret = 0;
505                 break;
506
507         default:
508                 printf("Wrong Request\n");
509                 ret = -1;
510                 break;
511         }
512
513         if (pc) {
514                 pkgmgr_client_free(pc);
515                 pc = NULL;
516         }
517         return ret;
518 }
519
520 static int __is_authorized()
521 {
522         /* pkgcmd needs root or developer privileges.
523            If launched via fork/exec, the launching program 
524            must be running as root */
525
526         uid_t uid = getuid();
527         if ((uid_t) 0 == uid || (uid_t) 5100 == uid)
528                 return 1;
529         else
530                 return 0;
531 }
532
533 int main(int argc, char *argv[])
534 {
535         optind = 1;
536         int opt_idx = 0;
537         int c = -1;
538         int ret = -1;
539
540         if (!__is_authorized()) {
541                 printf("You are not an authorized user!\n");
542                 return -1;
543         }
544
545         if (argc == 1)
546                 __print_usage();
547
548         data.request = -1;
549         memset(data.des_path, '\0', PKG_NAME_STRING_LEN_MAX);
550         memset(data.pkg_path, '\0', PKG_NAME_STRING_LEN_MAX);
551         memset(data.pkg_name, '\0', PKG_NAME_STRING_LEN_MAX);
552         memset(data.pkg_type, '\0', PKG_TYPE_STRING_LEN_MAX);
553         data.quiet = 0;
554         data.result = 0;
555         while (1) {
556                 c = getopt_long(argc, argv, short_options, long_options,
557                                 &opt_idx);
558                 if (c == -1)
559                         break;  /* Parse end */
560                 switch (c) {
561                 case 'i':       /* install */
562                         data.request = INSTALL_REQ;
563                         break;
564
565                 case 'u':       /* uninstall */
566                         data.request = UNINSTALL_REQ;
567                         break;
568
569                 case 'c':       /* clear */
570                         data.request = CLEAR_REQ;
571                         break;
572
573                 case 'A':       /* activate */
574                         data.request = ACTIVATE_REQ;
575                         break;
576
577                 case 'D':       /* deactivate */
578                         data.request = DEACTIVATE_REQ;
579                         break;
580
581                 case 'l':       /* list */
582                         data.request = LIST_REQ;
583                         break;
584
585                 case 's':       /* show */
586                         data.request = SHOW_REQ;
587                         break;
588
589                 case 'p':       /* package path */
590                         if (optarg)
591                                 strncpy(data.pkg_path, optarg,
592                                         PKG_NAME_STRING_LEN_MAX);
593                         ret = __convert_to_absolute_path(data.pkg_path);
594                         if (ret == -1) {
595                                 printf("conversion of relative path to absolute path failed\n");
596                                 return -1;
597                         }
598                         printf("package path is %s\n", data.pkg_path);
599                         break;
600
601                 case 'd':       /* descriptor path */
602                         if (optarg)
603                                 strncpy(data.des_path, optarg,
604                                         PKG_NAME_STRING_LEN_MAX);
605                         break;
606
607                 case 'n':       /* package name */
608                         if (optarg)
609                                 strncpy(data.pkg_name, optarg,
610                                         PKG_NAME_STRING_LEN_MAX);
611                         break;
612
613                 case 't':       /* package type */
614                         if (optarg)
615                                 strncpy(data.pkg_type, optarg,
616                                         PKG_TYPE_STRING_LEN_MAX);
617                         break;
618
619                 case 'h':       /* help */
620                         data.request = HELP_REQ;
621                         break;
622
623                 case 'q':       /* quiet mode */
624                         data.quiet = 1;
625                         break;
626
627                         /* Otherwise */
628                 case '?':       /* Not an option */
629                         __print_usage();
630                         break;
631
632                 case ':':       /* */
633                         break;
634
635                 default:
636                         break;
637
638                 }
639         }
640         ret = __process_request();
641         if (ret != 0) {
642                 printf("processing request %d failed\n", data.request);
643         }
644         return ret;
645 }