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