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