tpk/wgt backend will run as system session
[platform/core/appfw/slp-pkgmgr.git] / installer / pkgmgr_installer.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
24
25 #include <stdlib.h>
26 #include <unistd.h>
27 #include <string.h>
28 #include <getopt.h>
29
30 #include <gio/gio.h>
31
32 #include "pkgmgr_installer.h"
33 #include "pkgmgr_installer_config.h"
34 #include "pkgmgr_installer_debug.h"
35 #include "pkgmgr_installer_info.h"
36
37 #include "../client/include/comm_config.h"
38
39 #include <pkgmgr-info.h>
40
41 /* API export macro */
42 #ifndef API
43 #define API __attribute__ ((visibility("default")))
44 #endif
45
46 #define MAX_STRLEN 1024
47 #define MAX_QUERY_LEN   4096
48
49 #define CHK_PI_RET(r) \
50         do { if (NULL == pi) return (r); } while (0)
51
52 struct pkgmgr_installer {
53         int request_type;
54         int move_type;
55         char *pkgmgr_info;
56         char *session_id;
57         char *license_path;
58         char *optional_data;
59         char *caller_pkgid;
60         uid_t target_uid;
61         char *tep_path;
62         int tep_move;
63         int is_tep_included;
64         int is_preload;
65         int force_removal;
66         GDBusConnection *conn;
67 };
68
69 static uid_t g_target_uid;
70
71 static const char *__get_signal_name(pkgmgr_installer *pi, const char *key)
72 {
73         if (strcmp(key, PKGMGR_INSTALLER_INSTALL_PERCENT_KEY_STR) == 0)
74                 return COMM_STATUS_BROADCAST_EVENT_INSTALL_PROGRESS;
75         else if (strcmp(key, PKGMGR_INSTALLER_GET_SIZE_KEY_STR) == 0)
76                 return COMM_STATUS_BROADCAST_EVENT_GET_SIZE;
77         else if (strcmp(key, PKGMGR_INSTALLER_APPID_KEY_STR) == 0)
78                 return COMM_STATUS_BROADCAST_EVENT_UNINSTALL;
79
80         switch (pi->request_type) {
81         case PKGMGR_REQ_INSTALL:
82         case PKGMGR_REQ_MANIFEST_DIRECT_INSTALL:
83         case PKGMGR_REQ_MOUNT_INSTALL:
84                 return COMM_STATUS_BROADCAST_EVENT_INSTALL;
85         case PKGMGR_REQ_UNINSTALL:
86                 return COMM_STATUS_BROADCAST_EVENT_UNINSTALL;
87         case PKGMGR_REQ_UPGRADE:
88                 return COMM_STATUS_BROADCAST_EVENT_UPGRADE;
89         case PKGMGR_REQ_MOVE:
90                 return COMM_STATUS_BROADCAST_EVENT_MOVE;
91         case PKGMGR_REQ_ENABLE_APP:
92                 return COMM_STATUS_BROADCAST_EVENT_ENABLE_APP;
93         case PKGMGR_REQ_DISABLE_APP:
94                 return COMM_STATUS_BROADCAST_EVENT_DISABLE_APP;
95         case PKGMGR_REQ_ENABLE_APP_SPLASH_SCREEN:
96                 return COMM_STATUS_BROADCAST_EVENT_ENABLE_APP_SPLASH_SCREEN;
97         case PKGMGR_REQ_DISABLE_APP_SPLASH_SCREEN:
98                 return COMM_STATUS_BROADCAST_EVENT_DISABLE_APP_SPLASH_SCREEN;
99         }
100
101         ERR("cannot find type, send signal with type SIGNAL_STATUS");
102
103         return COMM_STATUS_BROADCAST_SIGNAL_STATUS;
104 }
105
106 static int __send_signal_for_app_event(pkgmgr_installer *pi, const char *pkg_type,
107                 const char *pkgid, const char *appid, const char *key, const char *val)
108 {
109         char *sid;
110         const char *name;
111         GError *err = NULL;
112
113         if (!pi || pi->conn == NULL || appid == NULL)
114                 return -1;
115
116         sid = pi->session_id;
117         if (!sid)
118                 sid = "";
119
120         name = __get_signal_name(pi, key);
121         if (name == NULL) {
122                 ERR("unknown signal type");
123                 return -1;
124         }
125
126         if (g_dbus_connection_emit_signal(pi->conn, NULL,
127                                 COMM_STATUS_BROADCAST_OBJECT_PATH,
128                                 COMM_STATUS_BROADCAST_INTERFACE, name,
129                                 g_variant_new("(ussssss)", pi->target_uid, sid,
130                                         pkg_type, pkgid, appid, key, val), &err)
131                         != TRUE) {
132                 ERR("failed to send dbus signal: %s", err->message);
133                 g_error_free(err);
134                 return -1;
135         }
136
137         return 0;
138 }
139
140 static int __send_signal_for_event(pkgmgr_installer *pi, const char *pkg_type,
141                 const char *pkgid, const char *key, const char *val)
142 {
143         char *sid;
144         const char *name;
145         GError *err = NULL;
146
147         if (!pi || pi->conn == NULL)
148                 return -1;
149
150         sid = pi->session_id;
151         if (!sid)
152                 sid = "";
153
154         name = __get_signal_name(pi, key);
155         if (name == NULL) {
156                 ERR("unknown signal type");
157                 return -1;
158         }
159
160         if (g_dbus_connection_emit_signal(pi->conn, NULL,
161                                 COMM_STATUS_BROADCAST_OBJECT_PATH,
162                                 COMM_STATUS_BROADCAST_INTERFACE, name,
163                                 g_variant_new("(ussssss)", pi->target_uid, sid,
164                                         pkg_type, pkgid, "", key, val), &err)
165                         != TRUE) {
166                 ERR("failed to send dbus signal: %s", err->message);
167                 g_error_free(err);
168                 return -1;
169         }
170
171         return 0;
172 }
173
174 API pkgmgr_installer *pkgmgr_installer_new(void)
175 {
176         pkgmgr_installer *pi;
177         GError *err = NULL;
178
179         pi = calloc(1, sizeof(struct pkgmgr_installer));
180         if (pi == NULL)
181                 return NULL;
182
183         pi->conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &err);
184         if (pi->conn == NULL) {
185                 ERR("failed to get bus: %s", err->message);
186                 g_error_free(err);
187                 free(pi);
188                 return NULL;
189         }
190
191         pi->tep_path = NULL;
192         pi->tep_move = 0;
193         pi->request_type = PKGMGR_REQ_INVALID;
194
195         return pi;
196 }
197
198 API pkgmgr_installer *pkgmgr_installer_offline_new(void)
199 {
200         pkgmgr_installer *pi;
201
202         pi = calloc(1, sizeof(struct pkgmgr_installer));
203         if (pi == NULL)
204                 return NULL;
205
206         pi->tep_path = NULL;
207         pi->tep_move = 0;
208         pi->request_type = PKGMGR_REQ_INVALID;
209
210         return pi;
211 }
212
213 API int pkgmgr_installer_free(pkgmgr_installer *pi)
214 {
215         CHK_PI_RET(-EINVAL);
216
217         /* free members */
218         if (pi->pkgmgr_info)
219                 free(pi->pkgmgr_info);
220         if (pi->session_id)
221                 free(pi->session_id);
222         if (pi->optional_data)
223                 free(pi->optional_data);
224         if (pi->caller_pkgid)
225                 free(pi->caller_pkgid);
226         if (pi->tep_path)
227                 free(pi->tep_path);
228
229         if (pi->conn) {
230                 g_dbus_connection_flush_sync(pi->conn, NULL, NULL);
231                 g_object_unref(pi->conn);
232         }
233
234         free(pi);
235
236         return 0;
237 }
238
239 API int
240 pkgmgr_installer_receive_request(pkgmgr_installer *pi,
241                                  const int argc, char **argv)
242 {
243         CHK_PI_RET(-EINVAL);
244
245         int r = 0;
246
247         /* Parse argv */
248         optind = 1;             /* Initialize optind to clear prev. index */
249         int opt_idx = 0;
250         int c;
251         int mode = 0;
252
253         pi->target_uid = getuid();
254         g_target_uid = pi->target_uid;
255         while (1) {
256                 c = getopt_long(argc, argv, short_opts, long_opts, &opt_idx);
257                 /* printf("c=%d %c\n", c, c); //debug */
258                 if (-1 == c)
259                         break;  /* Parse is end */
260                 switch (c) {
261                 case OPTVAL_PRELOAD:    /* request for preload app */
262                         pi->is_preload = 1;
263                         DBG("preload request [%d]", pi->is_preload);
264                         break;
265                 case OPTVAL_FORCE_REMOVAL:      /* request for force-remove */
266                         pi->force_removal = 1;
267                         DBG("force-remove request [%d]", pi->force_removal);
268                         break;
269                 case 'k':       /* session id */
270                         if (pi->session_id)
271                                 free(pi->session_id);
272                         pi->session_id = strndup(optarg, MAX_STRLEN);
273                         break;
274
275                 case 'l':       /* license path */
276                         if (pi->license_path)
277                                 free(pi->license_path);
278                         pi->license_path = strndup(optarg, MAX_STRLEN);
279                         break;
280
281                 case 'i':       /* install */
282                         if (mode) {
283                                 r = -EINVAL;
284                                 goto RET;
285                         }
286                         mode = 'i';
287                         pi->request_type = PKGMGR_REQ_INSTALL;
288                         if (pi->pkgmgr_info)
289                                 free(pi->pkgmgr_info);
290                         pi->pkgmgr_info = strndup(optarg, MAX_STRLEN);
291                         DBG("option is [i] pkgid[%s]", pi->pkgmgr_info);
292                         if (pi->pkgmgr_info && strlen(pi->pkgmgr_info) == 0)
293                                 free(pi->pkgmgr_info);
294                         else
295                                 mode = 'i';
296                         break;
297
298                 case 'e':       /* install */
299                         if (pi->tep_path)
300                                 free(pi->tep_path);
301                         pi->tep_path = strndup(optarg, MAX_STRLEN);
302                         pi->is_tep_included = 1;
303                         DBG("option is [e] tep_path[%s]", pi->tep_path);
304                         break;
305
306                 case 'M':       /* install */
307                         if (strcmp(optarg, "tep_move") == 0)
308                                 pi->tep_move = 1;
309                         else
310                                 pi->tep_move = 0;
311                         DBG("option is [M] tep_move[%d]", pi->tep_move);
312                         break;
313
314                 case 'd':       /* uninstall */
315                         if (mode) {
316                                 r = -EINVAL;
317                                 goto RET;
318                         }
319                         mode = 'd';
320                         pi->request_type = PKGMGR_REQ_UNINSTALL;
321                         if (pi->pkgmgr_info)
322                                 free(pi->pkgmgr_info);
323                         pi->pkgmgr_info = strndup(optarg, MAX_STRLEN);
324                         break;
325
326
327                 case 'c':       /* clear */
328                         if (mode) {
329                                 r = -EINVAL;
330                                 goto RET;
331                         }
332                         mode = 'c';
333                         pi->request_type = PKGMGR_REQ_CLEAR;
334                         if (pi->pkgmgr_info)
335                                 free(pi->pkgmgr_info);
336                         pi->pkgmgr_info = strndup(optarg, MAX_STRLEN);
337                         break;
338
339                 case 'm':       /* move */
340                         if (mode) {
341                                 r = -EINVAL;
342                                 goto RET;
343                         }
344                         mode = 'm';
345                         pi->request_type = PKGMGR_REQ_MOVE;
346                         if (pi->pkgmgr_info)
347                                 free(pi->pkgmgr_info);
348                         pi->pkgmgr_info = strndup(optarg, MAX_STRLEN);
349                         break;
350
351                 case 'r':       /* reinstall */
352                         if (mode) {
353                                 r = -EINVAL;
354                                 goto RET;
355                         }
356                         mode = 'r';
357                         pi->request_type = PKGMGR_REQ_REINSTALL;
358                         if (pi->pkgmgr_info)
359                                 free(pi->pkgmgr_info);
360                         pi->pkgmgr_info = strndup(optarg, MAX_STRLEN);
361                         break;
362
363                 case 't': /* move type*/
364                         pi->move_type = atoi(optarg);
365                         break;
366
367                 case 'p': /* caller pkgid*/
368                         if (pi->caller_pkgid)
369                                 free(pi->caller_pkgid);
370                         pi->caller_pkgid = strndup(optarg, MAX_STRLEN);
371
372                         break;
373
374                 case 's':       /* smack */
375                         if (mode) {
376                                 r = -EINVAL;
377                                 goto RET;
378                         }
379                         mode = 's';
380                         pi->request_type = PKGMGR_REQ_SMACK;
381                         if (pi->pkgmgr_info)
382                                 free(pi->pkgmgr_info);
383                         pi->pkgmgr_info = strndup(optarg, MAX_STRLEN);
384                         break;
385
386                 case 'o': /* optional data*/
387                         pi->optional_data = strndup(optarg, MAX_STRLEN);
388                         break;
389
390                 case 'y': /* pkgid for direct manifest installation */
391                         mode = 'y';
392                         pi->request_type = PKGMGR_REQ_MANIFEST_DIRECT_INSTALL;
393                         pi->pkgmgr_info = strndup(optarg, MAX_STRLEN);
394                         break;
395
396                 case 'w': /* pkgid for mount installation */
397                         mode = 'w';
398                         pi->request_type = PKGMGR_REQ_MOUNT_INSTALL;
399                         pi->pkgmgr_info = strndup(optarg, MAX_STRLEN);
400                         break;
401
402                 case 'b': /* recovery */
403                         if (mode) {
404                                 r = -EINVAL;
405                                 goto RET;
406                         }
407                         mode = 'b';
408                         pi->request_type = PKGMGR_REQ_RECOVER;
409                         if (pi->pkgmgr_info)
410                                 free(pi->pkgmgr_info);
411                         pi->pkgmgr_info = strndup(optarg, MAX_STRLEN);
412                         break;
413
414                 case 'D': /* disable pkg */
415                         pi->request_type = PKGMGR_REQ_DISABLE_PKG;
416                         if (pi->pkgmgr_info)
417                                 free(pi->pkgmgr_info);
418                         pi->pkgmgr_info = strndup(optarg, MAX_STRLEN);
419                         break;
420
421                 case 'A': /* enable pkg */
422                         pi->request_type = PKGMGR_REQ_ENABLE_PKG;
423                         if (pi->pkgmgr_info)
424                                 free(pi->pkgmgr_info);
425                         pi->pkgmgr_info = strndup(optarg, MAX_STRLEN);
426                         break;
427
428                 case 'u': /* uid */
429                         pi->target_uid = (uid_t)atoi(optarg);
430                         break;
431
432                         /* Otherwise */
433                 case '?':       /* Not an option */
434                         break;
435
436                 case ':':       /* */
437                         break;
438
439                 }
440         }
441
442  RET:
443         return r;
444 }
445
446 API int pkgmgr_installer_get_request_type(pkgmgr_installer *pi)
447 {
448         CHK_PI_RET(PKGMGR_REQ_INVALID);
449         return pi->request_type;
450 }
451
452 API uid_t pkgmgr_installer_get_uid(pkgmgr_installer *pi)
453 {
454         CHK_PI_RET(PKGMGR_REQ_INVALID);
455         return pi->target_uid;
456 }
457
458 API const char *pkgmgr_installer_get_request_info(pkgmgr_installer *pi)
459 {
460         CHK_PI_RET(PKGMGR_REQ_INVALID);
461         return pi->pkgmgr_info;
462 }
463
464 API const char *pkgmgr_installer_get_tep_path(pkgmgr_installer *pi)
465 {
466         CHK_PI_RET(PKGMGR_REQ_INVALID);
467         return pi->tep_path;
468 }
469
470 API int pkgmgr_installer_get_tep_move_type(pkgmgr_installer *pi)
471 {
472         CHK_PI_RET(PKGMGR_REQ_INVALID);
473         return pi->tep_move;
474 }
475
476 API const char *pkgmgr_installer_get_session_id(pkgmgr_installer *pi)
477 {
478         CHK_PI_RET(PKGMGR_REQ_INVALID);
479         return pi->session_id;
480 }
481
482 API const char *pkgmgr_installer_get_license_path(pkgmgr_installer *pi)
483 {
484         CHK_PI_RET(PKGMGR_REQ_INVALID);
485         return pi->license_path;
486 }
487
488 API const char *pkgmgr_installer_get_optional_data(pkgmgr_installer *pi)
489 {
490         CHK_PI_RET(PKGMGR_REQ_INVALID);
491         return pi->optional_data;
492 }
493
494 API int pkgmgr_installer_is_quiet(pkgmgr_installer *pi)
495 {
496         return 1;
497 }
498
499 API int pkgmgr_installer_get_move_type(pkgmgr_installer *pi)
500 {
501         CHK_PI_RET(PKGMGR_REQ_INVALID);
502         return pi->move_type;
503 }
504
505 API const char *pkgmgr_installer_get_caller_pkgid(pkgmgr_installer *pi)
506 {
507         CHK_PI_RET(PKGMGR_REQ_INVALID);
508         return pi->caller_pkgid;
509 }
510
511 API int pkgmgr_installer_get_is_preload(pkgmgr_installer *pi)
512 {
513         CHK_PI_RET(PKGMGR_REQ_INVALID);
514         return pi->is_preload;
515 }
516
517 API int pkgmgr_installer_get_force_removal(pkgmgr_installer *pi)
518 {
519         CHK_PI_RET(PKGMGR_REQ_INVALID);
520         return pi->force_removal;
521 }
522
523 API int pkgmgr_installer_send_app_uninstall_signal(pkgmgr_installer *pi,
524                              const char *pkg_type,
525                              const char *pkgid,
526                              const char *val)
527 {
528         int ret = 0;
529         ret = __send_signal_for_event(pi, pkg_type, pkgid,
530                         PKGMGR_INSTALLER_APPID_KEY_STR, val);
531         return ret;
532 }
533
534 API int pkgmgr_installer_set_uid(pkgmgr_installer *pi, uid_t uid)
535 {
536         if (pi == NULL)
537                 return -1;
538
539         pi->target_uid = uid;
540         g_target_uid = pi->target_uid;
541
542         return 0;
543 }
544
545 API int
546 pkgmgr_installer_send_app_signal(pkgmgr_installer *pi,
547                              const char *pkg_type,
548                              const char *pkgid,
549                              const char *appid,
550                              const char *key, const char *val)
551 {
552         int r = 0;
553
554         if (!pi->conn) {
555                 ERR("connection is NULL");
556                 return -1;
557         }
558
559         r = __send_signal_for_app_event(pi, pkg_type, pkgid, appid, key, val);
560
561         return r;
562 }
563
564 API int
565 pkgmgr_installer_send_signal(pkgmgr_installer *pi,
566                              const char *pkg_type,
567                              const char *pkgid,
568                              const char *key, const char *val)
569 {
570         int r = 0;
571
572         if (!pi->conn) {
573                 ERR("connection is NULL");
574                 return -1;
575         }
576
577         if (strcmp(key, PKGMGR_INSTALLER_START_KEY_STR) == 0 &&
578                         strcmp(val, PKGMGR_INSTALLER_UPGRADE_EVENT_STR) == 0)
579                 pi->request_type = PKGMGR_REQ_UPGRADE;
580
581         r = __send_signal_for_event(pi, pkg_type, pkgid, key, val);
582
583         return r;
584 }
585
586 API int pkgmgr_installer_set_request_type(pkgmgr_installer *pi, int request_type)
587 {
588         if (pi == NULL)
589                 return -1;
590
591         pi->request_type = request_type;
592         return 0;
593 }
594
595 API int pkgmgr_installer_set_session_id(pkgmgr_installer *pi, const char *session_id)
596 {
597         if (pi == NULL || session_id == NULL)
598                 return -1;
599
600         pi->session_id = strndup(session_id, MAX_STRLEN);
601         return 0;
602 }
603
604 API int pkgmgr_installer_create_certinfo_set_handle(pkgmgr_instcertinfo_h *handle)
605 {
606         int ret = 0;
607         ret = pkgmgrinfo_create_certinfo_set_handle(handle);
608         return ret;
609 }
610
611 API int pkgmgr_installer_set_cert_value(pkgmgr_instcertinfo_h handle, pkgmgr_instcert_type cert_type, char *cert_value)
612 {
613         int ret = 0;
614         ret = pkgmgrinfo_set_cert_value(handle, cert_type, cert_value);
615         return ret;
616 }
617
618 API int pkgmgr_installer_save_certinfo(const char *pkgid, pkgmgr_instcertinfo_h handle, uid_t uid)
619 {
620         int ret = 0;
621         ret = pkgmgrinfo_save_certinfo(pkgid, handle, uid);
622         return ret;
623 }
624
625 API int pkgmgr_installer_destroy_certinfo_set_handle(pkgmgr_instcertinfo_h handle)
626 {
627         int ret = 0;
628         ret = pkgmgrinfo_destroy_certinfo_set_handle(handle);
629         return ret;
630 }
631
632 API int pkgmgr_installer_delete_certinfo(const char *pkgid)
633 {
634         int ret = 0;
635         ret = pkgmgrinfo_delete_certinfo(pkgid);
636         return ret;
637 }
638
639 API int pkgmgr_installer_info_get_target_uid(uid_t *uid)
640 {
641         *uid = g_target_uid;
642
643         return 0;
644 }