Fix closing dbus connection
[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
61         GDBusConnection *conn;
62 };
63
64 static const char *__get_signal_name(int status_type)
65 {
66         switch (status_type) {
67         case COMM_STATUS_BROADCAST_ALL:
68                 return COMM_STATUS_BROADCAST_SIGNAL_STATUS;
69         case COMM_STATUS_BROADCAST_INSTALL:
70                 return COMM_STATUS_BROADCAST_EVENT_INSTALL;
71         case COMM_STATUS_BROADCAST_UNINSTALL:
72                 return COMM_STATUS_BROADCAST_EVENT_UNINSTALL;
73         case COMM_STATUS_BROADCAST_MOVE:
74                 return COMM_STATUS_BROADCAST_EVENT_MOVE;
75         case COMM_STATUS_BROADCAST_INSTALL_PROGRESS:
76                 return COMM_STATUS_BROADCAST_EVENT_INSTALL_PROGRESS;
77         case COMM_STATUS_BROADCAST_UPGRADE:
78                 return COMM_STATUS_BROADCAST_EVENT_UPGRADE;
79         case COMM_STATUS_BROADCAST_GET_SIZE:
80                 return COMM_STATUS_BROADCAST_EVENT_GET_SIZE;
81         default:
82                 return NULL;
83         }
84 }
85
86 static int __send_signal_for_event(int comm_status_type, pkgmgr_installer *pi,
87                              const char *pkg_type,
88                              const char *pkgid,
89                              const char *key, const char *val)
90 {
91         char *sid;
92         const char *name;
93         GError *err = NULL;
94
95         if (!pi || pi->conn == NULL)
96                 return -1;
97
98         sid = pi->session_id;
99         if (!sid)
100                 sid = "";
101
102         name = __get_signal_name(comm_status_type);
103         if (name == NULL) {
104                 ERR("unknown signal type");
105                 return -1;
106         }
107
108         if (g_dbus_connection_emit_signal(pi->conn, NULL,
109                                 COMM_STATUS_BROADCAST_OBJECT_PATH,
110                                 COMM_STATUS_BROADCAST_INTERFACE, name,
111                                 g_variant_new("(usssss)", getuid(), sid,
112                                         pkg_type, pkgid, key, val), &err)
113                         != TRUE) {
114                 ERR("failed to send dbus signal: %s", err->message);
115                 g_error_free(err);
116                 return -1;
117         }
118
119         return 0;
120 }
121
122 API int __send_event(pkgmgr_installer *pi,
123                              const char *pkg_type,
124                              const char *pkgid,
125                              const char *key, const char *val)
126 {
127         int r = -1;
128
129         if (strcmp(key,PKGMGR_INSTALLER_START_KEY_STR) == 0) {
130                 if(strcmp(key,PKGMGR_INSTALLER_UPGRADE_EVENT_STR) == 0) {
131                         pi->request_type = PKGMGR_REQ_UPGRADE;
132                         r = __send_signal_for_event(COMM_STATUS_BROADCAST_UPGRADE, pi, pkg_type, pkgid, key, val);
133                 }
134                 if(pi->request_type == PKGMGR_REQ_INSTALL) {
135                         r = __send_signal_for_event(COMM_STATUS_BROADCAST_INSTALL, pi, pkg_type, pkgid, key, val);
136                 } else if (pi->request_type == PKGMGR_REQ_UNINSTALL){
137                         r = __send_signal_for_event(COMM_STATUS_BROADCAST_UNINSTALL, pi, pkg_type, pkgid, key, val);
138                 }
139         } else if (strcmp(key,PKGMGR_INSTALLER_END_KEY_STR) == 0) {
140                 if(pi->request_type == PKGMGR_REQ_INSTALL) {
141                         r = __send_signal_for_event(COMM_STATUS_BROADCAST_INSTALL, pi, pkg_type, pkgid, key, val);
142                 } else if (pi->request_type == PKGMGR_REQ_UNINSTALL){
143                         r = __send_signal_for_event(COMM_STATUS_BROADCAST_UNINSTALL, pi, pkg_type, pkgid, key, val);
144                 } else if (pi->request_type == PKGMGR_REQ_UPGRADE){
145                         r = __send_signal_for_event(COMM_STATUS_BROADCAST_UPGRADE, pi, pkg_type, pkgid, key, val);
146                 }
147         } else if (strcmp(key,PKGMGR_INSTALLER_INSTALL_PERCENT_KEY_STR) == 0) {
148                 r = __send_signal_for_event(COMM_STATUS_BROADCAST_INSTALL_PROGRESS, pi, pkg_type, pkgid, key, val);
149         }
150
151         return r;
152 }
153
154 API pkgmgr_installer *pkgmgr_installer_new(void)
155 {
156         pkgmgr_installer *pi;
157         GError *err = NULL;
158
159         pi = calloc(1, sizeof(struct pkgmgr_installer));
160         if (pi == NULL)
161                 return NULL;
162
163         pi->conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &err);
164         if (pi->conn == NULL) {
165                 ERR("failed to get bus: %s", err->message);
166                 g_error_free(err);
167                 free(pi);
168                 return NULL;
169         }
170
171         pi->request_type = PKGMGR_REQ_INVALID;
172
173         return pi;
174 }
175
176 API int pkgmgr_installer_free(pkgmgr_installer *pi)
177 {
178         CHK_PI_RET(-EINVAL);
179
180         /* free members */
181         if (pi->pkgmgr_info)
182                 free(pi->pkgmgr_info);
183         if (pi->session_id)
184                 free(pi->session_id);
185         if (pi->optional_data)
186                 free(pi->optional_data);
187         if (pi->caller_pkgid)
188                 free(pi->caller_pkgid);
189
190         if (pi->conn) {
191                 g_dbus_connection_flush_sync(pi->conn, NULL, NULL);
192                 g_object_unref(pi->conn);
193         }
194
195         free(pi);
196
197         return 0;
198 }
199
200 API int
201 pkgmgr_installer_receive_request(pkgmgr_installer *pi,
202                                  const int argc, char **argv)
203 {
204         CHK_PI_RET(-EINVAL);
205
206         int r = 0;
207
208         /* Parse argv */
209         optind = 1;             /* Initialize optind to clear prev. index */
210         int opt_idx = 0;
211         int c;
212         int mode = 0;
213
214         pi->target_uid = getuid();
215         while (1) {
216                 c = getopt_long(argc, argv, short_opts, long_opts, &opt_idx);
217                 /* printf("c=%d %c\n", c, c); //debug */
218                 if (-1 == c)
219                         break;  /* Parse is end */
220                 switch (c) {
221                 case 'k':       /* session id */
222                         if (pi->session_id)
223                                 free(pi->session_id);
224                         pi->session_id = strndup(optarg, MAX_STRLEN);
225                         break;
226
227                 case 'l':       /* license path */
228                         if (pi->license_path)
229                                 free(pi->license_path);
230                         pi->license_path = strndup(optarg, MAX_STRLEN);
231                         break;
232
233                 case 'i':       /* install */
234                         if (mode) {
235                                 r = -EINVAL;
236                                 goto RET;
237                         }
238                         mode = 'i';
239                         pi->request_type = PKGMGR_REQ_INSTALL;
240                         if (pi->pkgmgr_info)
241                                 free(pi->pkgmgr_info);
242                         pi->pkgmgr_info = strndup(optarg, MAX_STRLEN);
243                         break;
244
245                 case 'd':       /* uninstall */
246                         if (mode) {
247                                 r = -EINVAL;
248                                 goto RET;
249                         }
250                         mode = 'd';
251                         pi->request_type = PKGMGR_REQ_UNINSTALL;
252                         if (pi->pkgmgr_info)
253                                 free(pi->pkgmgr_info);
254                         pi->pkgmgr_info = strndup(optarg, MAX_STRLEN);
255                         break;
256
257
258                 case 'c':       /* clear */
259                         if (mode) {
260                                 r = -EINVAL;
261                                 goto RET;
262                         }
263                         mode = 'c';
264                         pi->request_type = PKGMGR_REQ_CLEAR;
265                         if (pi->pkgmgr_info)
266                                 free(pi->pkgmgr_info);
267                         pi->pkgmgr_info = strndup(optarg, MAX_STRLEN);
268                         break;
269
270                 case 'm':       /* move */
271                         if (mode) {
272                                 r = -EINVAL;
273                                 goto RET;
274                         }
275                         mode = 'm';
276                         pi->request_type = PKGMGR_REQ_MOVE;
277                         if (pi->pkgmgr_info)
278                                 free(pi->pkgmgr_info);
279                         pi->pkgmgr_info = strndup(optarg, MAX_STRLEN);
280                         break;
281
282                 case 'r':       /* reinstall */
283                         if (mode) {
284                                 r = -EINVAL;
285                                 goto RET;
286                         }
287                         mode = 'r';
288                         pi->request_type = PKGMGR_REQ_REINSTALL;
289                         if (pi->pkgmgr_info)
290                                 free(pi->pkgmgr_info);
291                         pi->pkgmgr_info = strndup(optarg, MAX_STRLEN);
292                         break;
293
294                 case 't': /* move type*/
295                         pi->move_type = atoi(optarg);
296                         break;
297
298                 case 'p': /* caller pkgid*/
299                         if (pi->caller_pkgid)
300                                 free(pi->caller_pkgid);
301                         pi->caller_pkgid = strndup(optarg, MAX_STRLEN);
302
303                         break;
304
305                 case 's':       /* smack */
306                         if (mode) {
307                                 r = -EINVAL;
308                                 goto RET;
309                         }
310                         mode = 's';
311                         pi->request_type = PKGMGR_REQ_SMACK;
312                         if (pi->pkgmgr_info)
313                                 free(pi->pkgmgr_info);
314                         pi->pkgmgr_info = strndup(optarg, MAX_STRLEN);
315                         break;
316
317                 case 'o': /* optional data*/
318                         pi->optional_data = strndup(optarg, MAX_STRLEN);
319                         break;
320
321                         /* Otherwise */
322                 case '?':       /* Not an option */
323                         break;
324
325                 case ':':       /* */
326                         break;
327
328                 }
329         }
330
331  RET:
332         return r;
333 }
334
335 API int pkgmgr_installer_get_request_type(pkgmgr_installer *pi)
336 {
337         CHK_PI_RET(PKGMGR_REQ_INVALID);
338         return pi->request_type;
339 }
340
341 API const char *pkgmgr_installer_get_request_info(pkgmgr_installer *pi)
342 {
343         CHK_PI_RET(PKGMGR_REQ_INVALID);
344         return pi->pkgmgr_info;
345 }
346
347 API const char *pkgmgr_installer_get_session_id(pkgmgr_installer *pi)
348 {
349         CHK_PI_RET(PKGMGR_REQ_INVALID);
350         return pi->session_id;
351 }
352
353 API const char *pkgmgr_installer_get_license_path(pkgmgr_installer *pi)
354 {
355         CHK_PI_RET(PKGMGR_REQ_INVALID);
356         return pi->license_path;
357 }
358
359 API const char *pkgmgr_installer_get_optional_data(pkgmgr_installer *pi)
360 {
361         CHK_PI_RET(PKGMGR_REQ_INVALID);
362         return pi->optional_data;
363 }
364
365 API int pkgmgr_installer_is_quiet(pkgmgr_installer *pi)
366 {
367         return 1;
368 }
369
370 API int pkgmgr_installer_get_move_type(pkgmgr_installer *pi)
371 {
372         CHK_PI_RET(PKGMGR_REQ_INVALID);
373         return pi->move_type;
374 }
375
376 API const char *pkgmgr_installer_get_caller_pkgid(pkgmgr_installer *pi)
377 {
378         CHK_PI_RET(PKGMGR_REQ_INVALID);
379         return pi->caller_pkgid;
380 }
381
382 API int
383 pkgmgr_installer_send_signal(pkgmgr_installer *pi,
384                              const char *pkg_type,
385                              const char *pkgid,
386                              const char *key, const char *val)
387 {
388         int r = 0;
389         char *sid;
390
391         if (!pi->conn) {
392                 ERR("connection is NULL");
393                 return -1;
394         }
395
396         if (strcmp(pkg_type,PKGMGR_INSTALLER_GET_SIZE_KEY_STR) == 0) {
397                 r = __send_signal_for_event(COMM_STATUS_BROADCAST_GET_SIZE, pi, pkg_type, pkgid, key, val);
398                 return r;
399         }
400
401         sid = pi->session_id;
402         if (!sid)
403                 sid = "";
404
405         r = __send_event(pi, pkg_type, pkgid, key, val);
406
407         return r;
408 }
409
410 API int pkgmgr_installer_create_certinfo_set_handle(pkgmgr_instcertinfo_h *handle)
411 {
412         int ret = 0;
413         ret = pkgmgrinfo_create_certinfo_set_handle(handle);
414         return ret;
415 }
416
417 API int pkgmgr_installer_set_cert_value(pkgmgr_instcertinfo_h handle, pkgmgr_instcert_type cert_type, char *cert_value)
418 {
419         int ret = 0;
420         ret = pkgmgrinfo_set_cert_value(handle, cert_type, cert_value);
421         return ret;
422 }
423
424 API int pkgmgr_installer_save_certinfo(const char *pkgid, pkgmgr_instcertinfo_h handle, uid_t uid)
425 {
426         int ret = 0;
427         ret = pkgmgrinfo_save_certinfo(pkgid, handle, uid);
428         return ret;
429 }
430
431 API int pkgmgr_installer_destroy_certinfo_set_handle(pkgmgr_instcertinfo_h handle)
432 {
433         int ret = 0;
434         ret = pkgmgrinfo_destroy_certinfo_set_handle(handle);
435         return ret;
436 }
437
438 API int pkgmgr_installer_delete_certinfo(const char *pkgid)
439 {
440         int ret = 0;
441         ret = pkgmgrinfo_delete_certinfo(pkgid);
442         return ret;
443 }