4d4a21910035d50b6cfbb64bc3e0152758d8f9b0
[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_close_sync(pi->conn, NULL, NULL);
192
193         free(pi);
194
195         return 0;
196 }
197
198 API int
199 pkgmgr_installer_receive_request(pkgmgr_installer *pi,
200                                  const int argc, char **argv)
201 {
202         CHK_PI_RET(-EINVAL);
203
204         int r = 0;
205
206         /* Parse argv */
207         optind = 1;             /* Initialize optind to clear prev. index */
208         int opt_idx = 0;
209         int c;
210         int mode = 0;
211
212         pi->target_uid = getuid();
213         while (1) {
214                 c = getopt_long(argc, argv, short_opts, long_opts, &opt_idx);
215                 /* printf("c=%d %c\n", c, c); //debug */
216                 if (-1 == c)
217                         break;  /* Parse is end */
218                 switch (c) {
219                 case 'k':       /* session id */
220                         if (pi->session_id)
221                                 free(pi->session_id);
222                         pi->session_id = strndup(optarg, MAX_STRLEN);
223                         break;
224
225                 case 'l':       /* license path */
226                         if (pi->license_path)
227                                 free(pi->license_path);
228                         pi->license_path = strndup(optarg, MAX_STRLEN);
229                         break;
230
231                 case 'i':       /* install */
232                         if (mode) {
233                                 r = -EINVAL;
234                                 goto RET;
235                         }
236                         mode = 'i';
237                         pi->request_type = PKGMGR_REQ_INSTALL;
238                         if (pi->pkgmgr_info)
239                                 free(pi->pkgmgr_info);
240                         pi->pkgmgr_info = strndup(optarg, MAX_STRLEN);
241                         break;
242
243                 case 'd':       /* uninstall */
244                         if (mode) {
245                                 r = -EINVAL;
246                                 goto RET;
247                         }
248                         mode = 'd';
249                         pi->request_type = PKGMGR_REQ_UNINSTALL;
250                         if (pi->pkgmgr_info)
251                                 free(pi->pkgmgr_info);
252                         pi->pkgmgr_info = strndup(optarg, MAX_STRLEN);
253                         break;
254
255
256                 case 'c':       /* clear */
257                         if (mode) {
258                                 r = -EINVAL;
259                                 goto RET;
260                         }
261                         mode = 'c';
262                         pi->request_type = PKGMGR_REQ_CLEAR;
263                         if (pi->pkgmgr_info)
264                                 free(pi->pkgmgr_info);
265                         pi->pkgmgr_info = strndup(optarg, MAX_STRLEN);
266                         break;
267
268                 case 'm':       /* move */
269                         if (mode) {
270                                 r = -EINVAL;
271                                 goto RET;
272                         }
273                         mode = 'm';
274                         pi->request_type = PKGMGR_REQ_MOVE;
275                         if (pi->pkgmgr_info)
276                                 free(pi->pkgmgr_info);
277                         pi->pkgmgr_info = strndup(optarg, MAX_STRLEN);
278                         break;
279
280                 case 'r':       /* reinstall */
281                         if (mode) {
282                                 r = -EINVAL;
283                                 goto RET;
284                         }
285                         mode = 'r';
286                         pi->request_type = PKGMGR_REQ_REINSTALL;
287                         if (pi->pkgmgr_info)
288                                 free(pi->pkgmgr_info);
289                         pi->pkgmgr_info = strndup(optarg, MAX_STRLEN);
290                         break;
291
292                 case 't': /* move type*/
293                         pi->move_type = atoi(optarg);
294                         break;
295
296                 case 'p': /* caller pkgid*/
297                         if (pi->caller_pkgid)
298                                 free(pi->caller_pkgid);
299                         pi->caller_pkgid = strndup(optarg, MAX_STRLEN);
300
301                         break;
302
303                 case 's':       /* smack */
304                         if (mode) {
305                                 r = -EINVAL;
306                                 goto RET;
307                         }
308                         mode = 's';
309                         pi->request_type = PKGMGR_REQ_SMACK;
310                         if (pi->pkgmgr_info)
311                                 free(pi->pkgmgr_info);
312                         pi->pkgmgr_info = strndup(optarg, MAX_STRLEN);
313                         break;
314
315                 case 'o': /* optional data*/
316                         pi->optional_data = strndup(optarg, MAX_STRLEN);
317                         break;
318
319                         /* Otherwise */
320                 case '?':       /* Not an option */
321                         break;
322
323                 case ':':       /* */
324                         break;
325
326                 }
327         }
328
329  RET:
330         return r;
331 }
332
333 API int pkgmgr_installer_get_request_type(pkgmgr_installer *pi)
334 {
335         CHK_PI_RET(PKGMGR_REQ_INVALID);
336         return pi->request_type;
337 }
338
339 API const char *pkgmgr_installer_get_request_info(pkgmgr_installer *pi)
340 {
341         CHK_PI_RET(PKGMGR_REQ_INVALID);
342         return pi->pkgmgr_info;
343 }
344
345 API const char *pkgmgr_installer_get_session_id(pkgmgr_installer *pi)
346 {
347         CHK_PI_RET(PKGMGR_REQ_INVALID);
348         return pi->session_id;
349 }
350
351 API const char *pkgmgr_installer_get_license_path(pkgmgr_installer *pi)
352 {
353         CHK_PI_RET(PKGMGR_REQ_INVALID);
354         return pi->license_path;
355 }
356
357 API const char *pkgmgr_installer_get_optional_data(pkgmgr_installer *pi)
358 {
359         CHK_PI_RET(PKGMGR_REQ_INVALID);
360         return pi->optional_data;
361 }
362
363 API int pkgmgr_installer_is_quiet(pkgmgr_installer *pi)
364 {
365         return 1;
366 }
367
368 API int pkgmgr_installer_get_move_type(pkgmgr_installer *pi)
369 {
370         CHK_PI_RET(PKGMGR_REQ_INVALID);
371         return pi->move_type;
372 }
373
374 API const char *pkgmgr_installer_get_caller_pkgid(pkgmgr_installer *pi)
375 {
376         CHK_PI_RET(PKGMGR_REQ_INVALID);
377         return pi->caller_pkgid;
378 }
379
380 API int
381 pkgmgr_installer_send_signal(pkgmgr_installer *pi,
382                              const char *pkg_type,
383                              const char *pkgid,
384                              const char *key, const char *val)
385 {
386         int r = 0;
387         char *sid;
388
389         if (!pi->conn) {
390                 ERR("connection is NULL");
391                 return -1;
392         }
393
394         if (strcmp(pkg_type,PKGMGR_INSTALLER_GET_SIZE_KEY_STR) == 0) {
395                 r = __send_signal_for_event(COMM_STATUS_BROADCAST_GET_SIZE, pi, pkg_type, pkgid, key, val);
396                 return r;
397         }
398
399         sid = pi->session_id;
400         if (!sid)
401                 sid = "";
402
403         r = __send_event(pi, pkg_type, pkgid, key, val);
404
405         return r;
406 }
407
408 API int pkgmgr_installer_create_certinfo_set_handle(pkgmgr_instcertinfo_h *handle)
409 {
410         int ret = 0;
411         ret = pkgmgrinfo_create_certinfo_set_handle(handle);
412         return ret;
413 }
414
415 API int pkgmgr_installer_set_cert_value(pkgmgr_instcertinfo_h handle, pkgmgr_instcert_type cert_type, char *cert_value)
416 {
417         int ret = 0;
418         ret = pkgmgrinfo_set_cert_value(handle, cert_type, cert_value);
419         return ret;
420 }
421
422 API int pkgmgr_installer_save_certinfo(const char *pkgid, pkgmgr_instcertinfo_h handle, uid_t uid)
423 {
424         int ret = 0;
425         ret = pkgmgrinfo_save_certinfo(pkgid, handle, uid);
426         return ret;
427 }
428
429 API int pkgmgr_installer_destroy_certinfo_set_handle(pkgmgr_instcertinfo_h handle)
430 {
431         int ret = 0;
432         ret = pkgmgrinfo_destroy_certinfo_set_handle(handle);
433         return ret;
434 }
435
436 API int pkgmgr_installer_delete_certinfo(const char *pkgid)
437 {
438         int ret = 0;
439         ret = pkgmgrinfo_delete_certinfo(pkgid);
440         return ret;
441 }