fix change_info to get pkg info properly
[platform/core/appfw/pkgmgr-server.git] / src / request.c
1 #include <sys/types.h>
2 #include <sys/time.h>
3
4 #include <glib.h>
5 #include <gio/gio.h>
6
7 #include "comm_config.h"
8 #include "pm-queue.h"
9 #include "pkgmgr-server.h"
10 #include "package-manager.h"
11 #include "package-manager-debug.h"
12
13 static const char instropection_xml[] =
14         "<node>"
15         "  <interface name='org.tizen.pkgmgr'>"
16         "    <method name='install'>"
17         "      <arg type='u' name='uid' direction='in'/>"
18         "      <arg type='s' name='pkgtype' direction='in'/>"
19         "      <arg type='s' name='pkgpath' direction='in'/>"
20         "      <arg type='as' name='args' direction='in'/>"
21         "      <arg type='i' name='ret' direction='out'/>"
22         "      <arg type='s' name='reqkey' direction='out'/>"
23         "    </method>"
24         "    <method name='reinstall'>"
25         "      <arg type='u' name='uid' direction='in'/>"
26         "      <arg type='s' name='pkgtype' direction='in'/>"
27         "      <arg type='s' name='pkgid' direction='in'/>"
28         "      <arg type='i' name='ret' direction='out'/>"
29         "      <arg type='s' name='reqkey' direction='out'/>"
30         "    </method>"
31         "    <method name='uninstall'>"
32         "      <arg type='u' name='uid' direction='in'/>"
33         "      <arg type='s' name='pkgtype' direction='in'/>"
34         "      <arg type='s' name='pkgid' direction='in'/>"
35         "      <arg type='i' name='ret' direction='out'/>"
36         "      <arg type='s' name='reqkey' direction='out'/>"
37         "    </method>"
38         "    <method name='move'>"
39         "      <arg type='u' name='uid' direction='in'/>"
40         "      <arg type='s' name='pkgtype' direction='in'/>"
41         "      <arg type='s' name='pkgid' direction='in'/>"
42         "      <arg type='i' name='ret' direction='out'/>"
43         "      <arg type='s' name='reqkey' direction='out'/>"
44         "    </method>"
45         "    <method name='enable_pkg'>"
46         "      <arg type='u' name='uid' direction='in'/>"
47         "      <arg type='s' name='pkgid' direction='in'/>"
48         "      <arg type='i' name='ret' direction='out'/>"
49         "    </method>"
50         "    <method name='disable_pkg'>"
51         "      <arg type='u' name='uid' direction='in'/>"
52         "      <arg type='s' name='pkgid' direction='in'/>"
53         "      <arg type='i' name='ret' direction='out'/>"
54         "    </method>"
55         "    <method name='enable_app'>"
56         "      <arg type='u' name='uid' direction='in'/>"
57         "      <arg type='s' name='appid' direction='in'/>"
58         "      <arg type='i' name='ret' direction='out'/>"
59         "      <arg type='s' name='reqkey' direction='out'/>"
60         "    </method>"
61         "    <method name='disable_app'>"
62         "      <arg type='u' name='uid' direction='in'/>"
63         "      <arg type='s' name='appid' direction='in'/>"
64         "      <arg type='i' name='ret' direction='out'/>"
65         "      <arg type='s' name='reqkey' direction='out'/>"
66         "    </method>"
67         "    <method name='enable_global_app_for_uid'>"
68         "      <arg type='u' name='uid' direction='in'/>"
69         "      <arg type='s' name='appid' direction='in'/>"
70         "      <arg type='i' name='ret' direction='out'/>"
71         "      <arg type='s' name='reqkey' direction='out'/>"
72         "    </method>"
73         "    <method name='disable_global_app_for_uid'>"
74         "      <arg type='u' name='uid' direction='in'/>"
75         "      <arg type='s' name='appid' direction='in'/>"
76         "      <arg type='i' name='ret' direction='out'/>"
77         "      <arg type='s' name='reqkey' direction='out'/>"
78         "    </method>"
79         "    <method name='getsize'>"
80         "      <arg type='u' name='uid' direction='in'/>"
81         "      <arg type='s' name='pkgid' direction='in'/>"
82         "      <arg type='i' name='get_type' direction='in'/>"
83         "      <arg type='i' name='ret' direction='out'/>"
84         "      <arg type='s' name='reqkey' direction='out'/>"
85         "    </method>"
86         "    <method name='cleardata'>"
87         "      <arg type='u' name='uid' direction='in'/>"
88         "      <arg type='s' name='pkgtype' direction='in'/>"
89         "      <arg type='s' name='pkgid' direction='in'/>"
90         "      <arg type='i' name='ret' direction='out'/>"
91         "    </method>"
92         "    <method name='clearcache'>"
93         "      <arg type='u' name='uid' direction='in'/>"
94         "      <arg type='s' name='pkgid' direction='in'/>"
95         "      <arg type='i' name='ret' direction='out'/>"
96         "    </method>"
97         "    <method name='kill'>"
98         "      <arg type='u' name='uid' direction='in'/>"
99         "      <arg type='s' name='pkgid' direction='in'/>"
100         "      <arg type='i' name='ret' direction='out'/>"
101         "    </method>"
102         "    <method name='check'>"
103         "      <arg type='u' name='uid' direction='in'/>"
104         "      <arg type='s' name='pkgid' direction='in'/>"
105         "      <arg type='i' name='ret' direction='out'/>"
106         "    </method>"
107         "    <method name='generate_license_request'>"
108         "      <arg type='s' name='resp_data' direction='in'/>"
109         "      <arg type='i' name='ret' direction='out'/>"
110         "      <arg type='s' name='req_data' direction='out'/>"
111         "      <arg type='s' name='license_url' direction='out'/>"
112         "    </method>"
113         "    <method name='register_license'>"
114         "      <arg type='s' name='resp_data' direction='in'/>"
115         "      <arg type='i' name='ret' direction='out'/>"
116         "    </method>"
117         "    <method name='decrypt_package'>"
118         "      <arg type='s' name='drm_file_path' direction='in'/>"
119         "      <arg type='s' name='decrypted_file_path' direction='in'/>"
120         "      <arg type='i' name='ret' direction='out'/>"
121         "    </method>"
122         "    <method name='add_blacklist'>"
123         "      <arg type='u' name='uid' direction='in'/>"
124         "      <arg type='s' name='pkgid' direction='in'/>"
125         "      <arg type='i' name='ret' direction='out'/>"
126         "    </method>"
127         "    <method name='remove_blacklist'>"
128         "      <arg type='u' name='uid' direction='in'/>"
129         "      <arg type='s' name='pkgid' direction='in'/>"
130         "      <arg type='i' name='ret' direction='out'/>"
131         "    </method>"
132         "    <method name='check_blacklist'>"
133         "      <arg type='u' name='uid' direction='in'/>"
134         "      <arg type='s' name='pkgid' direction='in'/>"
135         "      <arg type='i' name='result' direction='out'/>"
136         "      <arg type='i' name='ret' direction='out'/>"
137         "    </method>"
138         "  </interface>"
139         "</node>";
140 static GDBusNodeInfo *instropection_data;
141 static guint reg_id;
142 static guint owner_id;
143 static GHashTable *req_table;
144
145 static char *__generate_reqkey(const char *pkgid)
146 {
147         struct timeval tv;
148         long curtime;
149         char timestr[MAX_PKG_ARGS_LEN];
150         char *str_req_key;
151         int size;
152
153         gettimeofday(&tv, NULL);
154         curtime = tv.tv_sec * 1000000 + tv.tv_usec;
155         snprintf(timestr, sizeof(timestr), "%ld", curtime);
156
157         size = strlen(pkgid) + strlen(timestr) + 2;
158         str_req_key = (char *)calloc(size, sizeof(char));
159         if (str_req_key == NULL) {
160                 DBG("calloc failed");
161                 return NULL;
162         }
163         snprintf(str_req_key, size, "%s_%s", pkgid, timestr);
164
165         return str_req_key;
166 }
167
168 static int __handle_request_install(uid_t uid,
169                 GDBusMethodInvocation *invocation, GVariant *parameters)
170 {
171         uid_t target_uid = (uid_t)-1;
172         char *pkgtype = NULL;
173         char *pkgpath = NULL;
174         char *args = NULL;
175         char *reqkey = NULL;
176         gchar **tmp_args = NULL;
177         gsize args_count;
178         int ret = -1;
179         GVariant *value;
180         gchar *str;
181         int i = 0;
182         int len = 0;
183
184         g_variant_get(parameters, "(u&s&s@as)", &target_uid, &pkgtype, &pkgpath, &value);
185         tmp_args = (gchar **)g_variant_get_strv(value, &args_count);
186
187         for (i = 0; i < args_count; i++)
188                 len = len + strlen(tmp_args[i]) + 1;
189
190         args = (char *)calloc(len, sizeof(char));
191         if (args == NULL) {
192                 ERR("calloc failed");
193                 ret =  -1;
194                 goto catch;
195         }
196
197         for (i = 0; i < args_count; i++) {
198                 strncat(args, tmp_args[i], strlen(tmp_args[i]));
199                 strncat(args, " ", strlen(" "));
200         }
201
202         if (target_uid == (uid_t)-1 || pkgtype == NULL) {
203                 g_dbus_method_invocation_return_value(invocation,
204                                 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
205                 ret = -1;
206                 goto catch;
207         }
208
209         if (pkgpath == NULL) {
210                 g_dbus_method_invocation_return_value(invocation,
211                                 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
212                 ret = -1;
213                 goto catch;
214         }
215
216         reqkey = __generate_reqkey(pkgpath);
217         if (reqkey == NULL) {
218                 ret = -1;
219                 goto catch;
220         }
221
222         if (_pm_queue_push(target_uid, reqkey, PKGMGR_REQUEST_TYPE_INSTALL, pkgtype,
223                                 pkgpath, args)) {
224                 g_dbus_method_invocation_return_value(invocation,
225                                 g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
226                 ret = -1;
227                 goto catch;
228         }
229
230         g_dbus_method_invocation_return_value(invocation,
231                         g_variant_new("(is)", PKGMGR_R_OK, reqkey));
232
233         ret = 0;
234
235 catch:
236         if (reqkey)
237                 free(reqkey);
238
239         if (args)
240                 free(args);
241
242         return ret;
243 }
244
245 static int __handle_request_reinstall(uid_t uid,
246                 GDBusMethodInvocation *invocation, GVariant *parameters)
247 {
248         uid_t target_uid = (uid_t)-1;
249         char *pkgtype = NULL;
250         char *pkgid = NULL;
251         char *reqkey;
252
253         g_variant_get(parameters, "(u&s&s)", &target_uid, &pkgtype, &pkgid);
254         if (target_uid == (uid_t)-1 || pkgtype == NULL || pkgid == NULL) {
255                 g_dbus_method_invocation_return_value(invocation,
256                                 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
257                 return -1;
258         }
259
260         reqkey = __generate_reqkey(pkgid);
261         if (reqkey == NULL)
262                 return -1;
263         if (_pm_queue_push(target_uid, reqkey, PKGMGR_REQUEST_TYPE_REINSTALL, pkgtype,
264                                 pkgid, "")) {
265                 g_dbus_method_invocation_return_value(invocation,
266                                 g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
267                 free(reqkey);
268                 return -1;
269         }
270
271         g_dbus_method_invocation_return_value(invocation,
272                         g_variant_new("(is)", PKGMGR_R_OK, reqkey));
273         free(reqkey);
274
275         return 0;
276 }
277
278 static int __handle_request_uninstall(uid_t uid,
279                 GDBusMethodInvocation *invocation, GVariant *parameters)
280 {
281         uid_t target_uid = (uid_t)-1;
282         char *pkgtype = NULL;
283         char *pkgid = NULL;
284         char *reqkey;
285
286         g_variant_get(parameters, "(u&s&s)", &target_uid, &pkgtype, &pkgid);
287         if (target_uid == (uid_t)-1 || pkgtype == NULL || pkgid == NULL) {
288                 g_dbus_method_invocation_return_value(invocation,
289                                 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
290                 return -1;
291         }
292
293         reqkey = __generate_reqkey(pkgid);
294         if (reqkey == NULL)
295                 return -1;
296         if (_pm_queue_push(target_uid, reqkey, PKGMGR_REQUEST_TYPE_UNINSTALL, pkgtype,
297                                 pkgid, "")) {
298                 g_dbus_method_invocation_return_value(invocation,
299                                 g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
300                 free(reqkey);
301                 return -1;
302         }
303
304         g_dbus_method_invocation_return_value(invocation,
305                         g_variant_new("(is)", PKGMGR_R_OK, reqkey));
306         free(reqkey);
307
308         return 0;
309 }
310
311 static int __handle_request_move(uid_t uid,
312                 GDBusMethodInvocation *invocation, GVariant *parameters)
313 {
314         uid_t target_uid = (uid_t)-1;
315         char *pkgtype = NULL;
316         char *pkgid = NULL;
317         char *reqkey;
318
319         g_variant_get(parameters, "(u&s&s)", &target_uid, &pkgtype, &pkgid);
320         if (target_uid == (uid_t)-1 || pkgtype == NULL || pkgid == NULL) {
321                 g_dbus_method_invocation_return_value(invocation,
322                                 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
323                 return -1;
324         }
325
326         reqkey = __generate_reqkey(pkgid);
327         if (reqkey == NULL)
328                 return -1;
329         if (_pm_queue_push(target_uid, reqkey, PKGMGR_REQUEST_TYPE_MOVE, pkgtype,
330                                 pkgid, "")) {
331                 g_dbus_method_invocation_return_value(invocation,
332                                 g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
333                 free(reqkey);
334                 return -1;
335         }
336
337         g_dbus_method_invocation_return_value(invocation,
338                         g_variant_new("(is)", PKGMGR_R_OK, reqkey));
339         free(reqkey);
340
341         return 0;
342 }
343
344 static int __handle_request_enable_pkg(uid_t uid,
345                 GDBusMethodInvocation *invocation, GVariant *parameters)
346 {
347         uid_t target_uid = (uid_t)-1;
348         char *pkgid = NULL;
349
350         g_variant_get(parameters, "(u&s)", &target_uid, &pkgid);
351         if (target_uid == (uid_t)-1 || pkgid == NULL) {
352                 g_dbus_method_invocation_return_value(invocation,
353                                 g_variant_new("(i)", PKGMGR_R_ECOMM));
354                 return -1;
355         }
356
357         if (_pm_queue_push(target_uid, "", PKGMGR_REQUEST_TYPE_ENABLE_PKG, "pkg",
358                                 pkgid, "")) {
359                 g_dbus_method_invocation_return_value(invocation,
360                                 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
361                 return -1;
362         }
363
364         g_dbus_method_invocation_return_value(invocation,
365                         g_variant_new("(i)", PKGMGR_R_OK));
366
367         return 0;
368 }
369
370 static int __handle_request_disable_pkg(uid_t uid,
371                 GDBusMethodInvocation *invocation, GVariant *parameters)
372 {
373         uid_t target_uid = (uid_t)-1;
374         char *pkgid = NULL;
375
376         g_variant_get(parameters, "(u&s)", &target_uid, &pkgid);
377         if (target_uid == (uid_t)-1 || pkgid == NULL) {
378                 g_dbus_method_invocation_return_value(invocation,
379                                 g_variant_new("(i)", PKGMGR_R_ECOMM));
380                 return -1;
381         }
382
383         if (_pm_queue_push(target_uid, "", PKGMGR_REQUEST_TYPE_DISABLE_PKG, "pkg",
384                                 pkgid, "")) {
385                 g_dbus_method_invocation_return_value(invocation,
386                                 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
387                 return -1;
388         }
389
390         g_dbus_method_invocation_return_value(invocation,
391                         g_variant_new("(i)", PKGMGR_R_OK));
392
393         return 0;
394 }
395
396 static int __handle_request_enable_app(uid_t uid,
397                 GDBusMethodInvocation *invocation, GVariant *parameters)
398 {
399         uid_t target_uid = (uid_t)-1;
400         char *appid = NULL;
401         char *reqkey = NULL;
402         int ret = -1;
403
404         g_variant_get(parameters, "(u&s)", &target_uid, &appid);
405         if (target_uid == (uid_t)-1 || appid == NULL) {
406                 g_dbus_method_invocation_return_value(invocation,
407                                 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
408                 return -1;
409         }
410
411         reqkey = __generate_reqkey(appid);
412         if (reqkey == NULL) {
413                 ret = -1;
414                 goto catch;
415         }
416
417         if (_pm_queue_push(target_uid, reqkey, PKGMGR_REQUEST_TYPE_ENABLE_APP, "app",
418                                 appid, "")) {
419                 g_dbus_method_invocation_return_value(invocation,
420                                 g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
421                 ret = -1;
422                 goto catch;
423         }
424
425         g_dbus_method_invocation_return_value(invocation,
426                         g_variant_new("(is)", PKGMGR_R_OK, reqkey));
427
428         ret = 0;
429
430 catch:
431         if(reqkey)
432                 free(reqkey);
433
434         return ret;
435 }
436
437 static int __handle_request_disable_app(uid_t uid,
438                 GDBusMethodInvocation *invocation, GVariant *parameters)
439 {
440         uid_t target_uid = (uid_t)-1;
441         char *appid = NULL;
442         char *reqkey = NULL;
443         int ret = -1;
444
445         g_variant_get(parameters, "(u&s)", &target_uid, &appid);
446         if (target_uid == (uid_t)-1 || appid == NULL) {
447                 g_dbus_method_invocation_return_value(invocation,
448                                 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
449                 return -1;
450         }
451
452         reqkey = __generate_reqkey(appid);
453         if (reqkey == NULL) {
454                 ret = -1;
455                 goto catch;
456         }
457
458         if (_pm_queue_push(target_uid, reqkey, PKGMGR_REQUEST_TYPE_DISABLE_APP, "app",
459                                 appid, "")) {
460                 g_dbus_method_invocation_return_value(invocation,
461                                 g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
462                 ret = -1;
463                 goto catch;
464         }
465
466         g_dbus_method_invocation_return_value(invocation,
467                         g_variant_new("(is)", PKGMGR_R_OK, reqkey));
468
469         ret = 0;
470
471 catch:
472         if (reqkey)
473                 free(reqkey);
474
475         return ret;
476 }
477
478 static int __handle_request_enable_global_app_for_uid(uid_t uid,
479                 GDBusMethodInvocation *invocation, GVariant *parameters)
480 {
481         uid_t target_uid = (uid_t)-1;
482         char *appid = NULL;
483         char *reqkey = NULL;
484         int ret = -1;
485
486         g_variant_get(parameters, "(u&s)", &target_uid, &appid);
487         if (target_uid == (uid_t)-1 || appid == NULL) {
488                 g_dbus_method_invocation_return_value(invocation,
489                                 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
490                 return -1;
491         }
492
493         reqkey = __generate_reqkey(appid);
494         if (reqkey == NULL) {
495                 ret = -1;
496                 goto catch;
497         }
498
499         if (_pm_queue_push(target_uid, reqkey, PKGMGR_REQUEST_TYPE_ENABLE_GLOBAL_APP_FOR_UID, "app",
500                                 appid, "")) {
501                 g_dbus_method_invocation_return_value(invocation,
502                                 g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
503                 ret = -1;
504                 goto catch;
505         }
506
507         g_dbus_method_invocation_return_value(invocation,
508                         g_variant_new("(is)", PKGMGR_R_OK, reqkey));
509
510         ret = 0;
511
512 catch:
513         if (reqkey)
514                 free(reqkey);
515
516         return ret;
517 }
518
519 static int __handle_request_disable_global_app_for_uid(uid_t uid,
520                 GDBusMethodInvocation *invocation, GVariant *parameters)
521 {
522         uid_t target_uid = (uid_t)-1;
523         char *appid = NULL;
524         char *reqkey = NULL;
525         int ret = -1;
526
527         g_variant_get(parameters, "(u&s)", &target_uid, &appid);
528         if (target_uid == (uid_t)-1 || appid == NULL) {
529                 g_dbus_method_invocation_return_value(invocation,
530                                 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
531                 return -1;
532         }
533
534         reqkey = __generate_reqkey(appid);
535         if (reqkey == NULL) {
536                 ret = -1;
537                 goto catch;
538         }
539
540         if (_pm_queue_push(target_uid, reqkey, PKGMGR_REQUEST_TYPE_DISABLE_GLOBAL_APP_FOR_UID, "app",
541                                 appid, "")) {
542                 g_dbus_method_invocation_return_value(invocation,
543                                 g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
544                 ret = -1;
545                 goto catch;
546         }
547
548         g_dbus_method_invocation_return_value(invocation,
549                         g_variant_new("(is)", PKGMGR_R_OK, reqkey));
550
551         ret = 0;
552
553 catch:
554         if (reqkey)
555                 free(reqkey);
556
557         return ret;
558 }
559
560 static int __handle_request_getsize(uid_t uid,
561                 GDBusMethodInvocation *invocation, GVariant *parameters)
562 {
563         uid_t target_uid = (uid_t)-1;
564         char *pkgid = NULL;
565         int get_type = -1;
566         char *reqkey;
567         char buf[4];
568
569         g_variant_get(parameters, "(u&si)", &target_uid, &pkgid, &get_type);
570         if (target_uid == (uid_t)-1 || pkgid == NULL || get_type == -1) {
571                 g_dbus_method_invocation_return_value(invocation,
572                                 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
573                 return -1;
574         }
575
576         reqkey = __generate_reqkey(pkgid);
577         if (reqkey == NULL)
578                 return -1;
579
580         snprintf(buf, sizeof(buf), "%d", get_type);
581         if (_pm_queue_push(target_uid, reqkey, PKGMGR_REQUEST_TYPE_GETSIZE, "getsize",
582                                 pkgid, buf)) {
583                 g_dbus_method_invocation_return_value(invocation,
584                                 g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
585                 free(reqkey);
586                 return -1;
587         }
588
589         g_dbus_method_invocation_return_value(invocation,
590                         g_variant_new("(is)", PKGMGR_R_OK, reqkey));
591         free(reqkey);
592
593         return 0;
594 }
595
596 static int __handle_request_cleardata(uid_t uid,
597                 GDBusMethodInvocation *invocation, GVariant *parameters)
598 {
599         uid_t target_uid = (uid_t)-1;
600         char *pkgtype = NULL;
601         char *pkgid = NULL;
602         char *reqkey = NULL;
603
604         g_variant_get(parameters, "(u&s&s)", &target_uid, &pkgtype, &pkgid);
605         if (target_uid == (uid_t)-1 || pkgtype == NULL || pkgid == NULL) {
606                 g_dbus_method_invocation_return_value(invocation,
607                                 g_variant_new("(i)", PKGMGR_R_ECOMM));
608                 return -1;
609         }
610
611         reqkey = __generate_reqkey(pkgid);
612         if (reqkey == NULL)
613                 return -1;
614
615         if (_pm_queue_push(target_uid, reqkey, PKGMGR_REQUEST_TYPE_CLEARDATA, pkgtype,
616                                 pkgid, "")) {
617                 g_dbus_method_invocation_return_value(invocation,
618                                 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
619                 return -1;
620         }
621
622         g_dbus_method_invocation_return_value(invocation,
623                         g_variant_new("(i)", PKGMGR_R_OK));
624
625         return 0;
626 }
627
628 static int __handle_request_clearcache(uid_t uid,
629                 GDBusMethodInvocation *invocation, GVariant *parameters)
630 {
631         uid_t target_uid = (uid_t)-1;
632         char *pkgid = NULL;
633
634         g_variant_get(parameters, "(u&s)", &target_uid, &pkgid);
635         if (target_uid == (uid_t)-1 || pkgid == NULL) {
636                 g_dbus_method_invocation_return_value(invocation,
637                                 g_variant_new("(i)", PKGMGR_R_ECOMM));
638                 return -1;
639         }
640
641         if (_pm_queue_push(target_uid, "", PKGMGR_REQUEST_TYPE_CLEARCACHE,
642                                 "clearcache", pkgid, "")) {
643                 g_dbus_method_invocation_return_value(invocation,
644                                 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
645                 return -1;
646         }
647
648         g_dbus_method_invocation_return_value(invocation,
649                         g_variant_new("(i)", PKGMGR_R_OK));
650
651         return 0;
652 }
653
654 static int __handle_request_kill(uid_t uid,
655                 GDBusMethodInvocation *invocation, GVariant *parameters)
656 {
657         uid_t target_uid = (uid_t)-1;
658         char *pkgid = NULL;
659
660         g_variant_get(parameters, "(u&s)", &target_uid, &pkgid);
661         if (target_uid == (uid_t)-1 || pkgid == NULL) {
662                 g_dbus_method_invocation_return_value(invocation,
663                                 g_variant_new("(i)", PKGMGR_R_ECOMM));
664                 return -1;
665         }
666
667         if (_pm_queue_push(target_uid, "", PKGMGR_REQUEST_TYPE_KILL, "pkg",
668                                 pkgid, "")) {
669                 g_dbus_method_invocation_return_value(invocation,
670                                 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
671                 return -1;
672         }
673
674         g_dbus_method_invocation_return_value(invocation,
675                         g_variant_new("(i)", PKGMGR_R_OK));
676
677         return 0;
678 }
679
680 static int __handle_request_check(uid_t uid,
681                 GDBusMethodInvocation *invocation, GVariant *parameters)
682 {
683         uid_t target_uid = (uid_t)-1;
684         char *pkgid = NULL;
685
686         g_variant_get(parameters, "(u&s)", &target_uid, &pkgid);
687         if (target_uid == (uid_t)-1 || pkgid == NULL) {
688                 g_dbus_method_invocation_return_value(invocation,
689                                 g_variant_new("(i)", PKGMGR_R_ECOMM));
690                 return -1;
691         }
692
693         if (_pm_queue_push(target_uid, "", PKGMGR_REQUEST_TYPE_CHECK, "pkg",
694                                 pkgid, "")) {
695                 g_dbus_method_invocation_return_value(invocation,
696                                 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
697                 return -1;
698         }
699
700         g_dbus_method_invocation_return_value(invocation,
701                         g_variant_new("(i)", PKGMGR_R_OK));
702
703         return 0;
704 }
705
706 static int __handle_request_generate_license_request(uid_t uid,
707                 GDBusMethodInvocation *invocation, GVariant *parameters)
708 {
709         char *reqkey;
710         char *resp_data = NULL;
711
712         g_variant_get(parameters, "(&s)", &resp_data);
713         if (resp_data == NULL) {
714                 g_dbus_method_invocation_return_value(invocation,
715                                 g_variant_new("(iss)", PKGMGR_R_ECOMM, "", ""));
716                 return -1;
717         }
718
719         reqkey = __generate_reqkey("drm");
720         if (reqkey == NULL) {
721                 g_dbus_method_invocation_return_value(invocation,
722                                 g_variant_new("(iss)", PKGMGR_R_ENOMEM, "",
723                                         ""));
724                 return -1;
725         }
726
727         if (_pm_queue_push(uid, reqkey,
728                                 PKGMGR_REQUEST_TYPE_GENERATE_LICENSE_REQUEST,
729                                 "pkg", "", resp_data)) {
730                 g_dbus_method_invocation_return_value(invocation,
731                                 g_variant_new("(iss)", PKGMGR_R_ESYSTEM, "",
732                                         ""));
733                 free(reqkey);
734                 return -1;
735         }
736
737         if (!g_hash_table_insert(req_table, (gpointer)reqkey,
738                                 (gpointer)invocation))
739                 ERR("reqkey already exists");
740
741         return 0;
742 }
743
744 static int __handle_request_register_license(uid_t uid,
745                 GDBusMethodInvocation *invocation, GVariant *parameters)
746 {
747         char *reqkey;
748         char *resp_data = NULL;
749
750         g_variant_get(parameters, "(&s)", &resp_data);
751         if (resp_data == NULL) {
752                 g_dbus_method_invocation_return_value(invocation,
753                                 g_variant_new("(i)", PKGMGR_R_ECOMM));
754                 return -1;
755         }
756
757         reqkey = __generate_reqkey("drm");
758         if (reqkey == NULL) {
759                 g_dbus_method_invocation_return_value(invocation,
760                                 g_variant_new("(i)", PKGMGR_R_ENOMEM));
761                 return -1;
762         }
763
764         if (_pm_queue_push(uid, reqkey, PKGMGR_REQUEST_TYPE_REGISTER_LICENSE,
765                                 "pkg", "", resp_data)) {
766                 g_dbus_method_invocation_return_value(invocation,
767                                 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
768                 free(reqkey);
769                 return -1;
770         }
771
772         if (!g_hash_table_insert(req_table, (gpointer)reqkey,
773                                 (gpointer)invocation))
774                 ERR("reqkey already exists");
775
776         return 0;
777 }
778
779 static int __handle_request_decrypt_package(uid_t uid,
780                 GDBusMethodInvocation *invocation, GVariant *parameters)
781 {
782         char *reqkey;
783         char *drm_file_path = NULL;
784         char *decrypted_file_path = NULL;
785
786         g_variant_get(parameters, "(&s&s)", &drm_file_path,
787                         &decrypted_file_path);
788         if (drm_file_path == NULL || decrypted_file_path == NULL) {
789                 g_dbus_method_invocation_return_value(invocation,
790                                 g_variant_new("(i)", PKGMGR_R_ECOMM));
791                 return -1;
792         }
793
794         reqkey = __generate_reqkey("drm");
795         if (reqkey == NULL) {
796                 g_dbus_method_invocation_return_value(invocation,
797                                 g_variant_new("(i)", PKGMGR_R_ENOMEM));
798                 return -1;
799         }
800
801         if (_pm_queue_push(uid, reqkey, PKGMGR_REQUEST_TYPE_DECRYPT_PACKAGE,
802                                 "pkg", drm_file_path, decrypted_file_path)) {
803                 g_dbus_method_invocation_return_value(invocation,
804                                 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
805                 free(reqkey);
806                 return -1;
807         }
808
809         if (!g_hash_table_insert(req_table, (gpointer)reqkey,
810                                 (gpointer)invocation))
811                 ERR("reqkey already exists");
812
813         return 0;
814 }
815
816 static int __handle_request_add_blacklist(uid_t uid,
817                 GDBusMethodInvocation *invocation, GVariant *parameters)
818 {
819         uid_t target_uid = (uid_t)-1;
820         char *reqkey;
821         char *pkgid = NULL;
822
823         g_variant_get(parameters, "(u&s)", &target_uid, &pkgid);
824         if (target_uid == (uid_t)-1 || pkgid == NULL) {
825                 g_dbus_method_invocation_return_value(invocation,
826                                 g_variant_new("(i)", PKGMGR_R_ECOMM));
827                 return -1;
828         }
829
830         reqkey = __generate_reqkey("blacklist");
831         if (reqkey == NULL) {
832                 g_dbus_method_invocation_return_value(invocation,
833                                 g_variant_new("(i)", PKGMGR_R_ENOMEM));
834                 return -1;
835         }
836
837         if (_pm_queue_push(target_uid, reqkey,
838                                 PKGMGR_REQUEST_TYPE_ADD_BLACKLIST,
839                                 "pkg", pkgid, "")) {
840                 g_dbus_method_invocation_return_value(invocation,
841                                 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
842                 return -1;
843         }
844
845         if (!g_hash_table_insert(req_table, (gpointer)reqkey,
846                                 (gpointer)invocation))
847                 ERR("reqkey already exists");
848
849         return 0;
850 }
851
852 static int __handle_request_remove_blacklist(uid_t uid,
853                 GDBusMethodInvocation *invocation, GVariant *parameters)
854 {
855         uid_t target_uid = (uid_t)-1;
856         char *reqkey;
857         char *pkgid = NULL;
858
859         g_variant_get(parameters, "(u&s)", &target_uid, &pkgid);
860         if (target_uid == (uid_t)-1 || pkgid == NULL) {
861                 g_dbus_method_invocation_return_value(invocation,
862                                 g_variant_new("(i)", PKGMGR_R_ECOMM));
863                 return -1;
864         }
865
866         reqkey = __generate_reqkey("blacklist");
867         if (reqkey == NULL) {
868                 g_dbus_method_invocation_return_value(invocation,
869                                 g_variant_new("(i)", PKGMGR_R_ENOMEM));
870                 return -1;
871         }
872
873         if (_pm_queue_push(target_uid, reqkey,
874                                 PKGMGR_REQUEST_TYPE_REMOVE_BLACKLIST,
875                                 "pkg", pkgid, "")) {
876                 g_dbus_method_invocation_return_value(invocation,
877                                 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
878                 return -1;
879         }
880
881         if (!g_hash_table_insert(req_table, (gpointer)reqkey,
882                                 (gpointer)invocation))
883                 ERR("reqkey already exists");
884
885         return 0;
886 }
887
888 static int __handle_request_check_blacklist(uid_t uid,
889                 GDBusMethodInvocation *invocation, GVariant *parameters)
890 {
891         uid_t target_uid = (uid_t)-1;
892         char *reqkey;
893         char *pkgid = NULL;
894
895         g_variant_get(parameters, "(u&s)", &target_uid, &pkgid);
896         if (target_uid == (uid_t)-1 || pkgid == NULL) {
897                 g_dbus_method_invocation_return_value(invocation,
898                                 g_variant_new("(i)", PKGMGR_R_ECOMM));
899                 return -1;
900         }
901
902         reqkey = __generate_reqkey("blacklist");
903         if (reqkey == NULL) {
904                 g_dbus_method_invocation_return_value(invocation,
905                                 g_variant_new("(i)", PKGMGR_R_ENOMEM));
906                 return -1;
907         }
908
909         if (_pm_queue_push(target_uid, reqkey,
910                                 PKGMGR_REQUEST_TYPE_CHECK_BLACKLIST,
911                                 "pkg", pkgid, "")) {
912                 g_dbus_method_invocation_return_value(invocation,
913                                 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
914                 return -1;
915         }
916
917         if (!g_hash_table_insert(req_table, (gpointer)reqkey,
918                                 (gpointer)invocation))
919                 ERR("reqkey already exists");
920
921         return 0;
922 }
923
924 static uid_t __get_caller_uid(GDBusConnection *connection, const char *name)
925 {
926         GError *err = NULL;
927         GVariant *result;
928         uid_t uid;
929
930         result = g_dbus_connection_call_sync(connection,
931                         "org.freedesktop.DBus", "/org/freedesktop/DBus",
932                         "org.freedesktop.DBus", "GetConnectionUnixUser",
933                         g_variant_new("(s)", name), NULL,
934                         G_DBUS_CALL_FLAGS_NONE, -1, NULL, &err);
935         if (result == NULL) {
936                 ERR("failed to get caller uid: %s", err->message);
937                 g_error_free(err);
938                 return (uid_t)-1;
939         }
940
941         g_variant_get(result, "(u)", &uid);
942
943         return uid;
944 }
945
946 static void __handle_method_call(GDBusConnection *connection,
947                 const gchar *sender, const gchar *object_path,
948                 const gchar *interface_name, const gchar *method_name,
949                 GVariant *parameters, GDBusMethodInvocation *invocation,
950                 gpointer user_data)
951 {
952         int ret;
953         uid_t uid;
954
955         uid = __get_caller_uid(connection,
956                 g_dbus_method_invocation_get_sender(invocation));
957         if (uid == (uid_t)-1)
958                 return;
959
960         if (g_strcmp0(method_name, "install") == 0)
961                 ret = __handle_request_install(uid, invocation, parameters);
962         else if (g_strcmp0(method_name, "reinstall") == 0)
963                 ret = __handle_request_reinstall(uid, invocation, parameters);
964         else if (g_strcmp0(method_name, "uninstall") == 0)
965                 ret = __handle_request_uninstall(uid, invocation, parameters);
966         else if (g_strcmp0(method_name, "cleardata") == 0)
967                 ret = __handle_request_cleardata(uid, invocation, parameters);
968         else if (g_strcmp0(method_name, "move") == 0)
969                 ret = __handle_request_move(uid, invocation, parameters);
970         else if (g_strcmp0(method_name, "enable") == 0)
971                 ret = __handle_request_enable_pkg(uid, invocation, parameters);
972         else if (g_strcmp0(method_name, "disable") == 0)
973                 ret = __handle_request_disable_pkg(uid, invocation, parameters);
974         else if (g_strcmp0(method_name, "getsize") == 0)
975                 ret = __handle_request_getsize(uid, invocation, parameters);
976         else if (g_strcmp0(method_name, "clearcache") == 0)
977                 ret = __handle_request_clearcache(uid, invocation, parameters);
978         else if (g_strcmp0(method_name, "enable_app") == 0)
979                 ret = __handle_request_enable_app(uid, invocation, parameters);
980         else if (g_strcmp0(method_name, "disable_app") == 0)
981                 ret = __handle_request_disable_app(uid, invocation, parameters);
982         else if (g_strcmp0(method_name, "enable_global_app_for_uid") == 0)
983                 ret = __handle_request_enable_global_app_for_uid(uid, invocation, parameters);
984         else if (g_strcmp0(method_name, "disable_global_app_for_uid") == 0)
985                 ret = __handle_request_disable_global_app_for_uid(uid, invocation, parameters);
986         else if (g_strcmp0(method_name, "kill") == 0)
987                 ret = __handle_request_kill(uid, invocation, parameters);
988         else if (g_strcmp0(method_name, "check") == 0)
989                 ret = __handle_request_check(uid, invocation, parameters);
990         else if (g_strcmp0(method_name, "generate_license_request") == 0)
991                 ret = __handle_request_generate_license_request(uid, invocation,
992                                 parameters);
993         else if (g_strcmp0(method_name, "register_license") == 0)
994                 ret = __handle_request_register_license(uid, invocation,
995                                 parameters);
996         else if (g_strcmp0(method_name, "decrypt_package") == 0)
997                 ret = __handle_request_decrypt_package(uid, invocation,
998                                 parameters);
999         else if (g_strcmp0(method_name, "add_blacklist") == 0)
1000                 ret = __handle_request_add_blacklist(uid, invocation,
1001                                 parameters);
1002         else if (g_strcmp0(method_name, "remove_blacklist") == 0)
1003                 ret = __handle_request_remove_blacklist(uid, invocation,
1004                                 parameters);
1005         else if (g_strcmp0(method_name, "check_blacklist") == 0)
1006                 ret = __handle_request_check_blacklist(uid, invocation,
1007                                 parameters);
1008         else
1009                 ret = -1;
1010
1011         if (ret == 0)
1012                 g_idle_add(queue_job, NULL);
1013 }
1014
1015 int __return_value_to_caller(const char *req_key, GVariant *result)
1016 {
1017         GDBusMethodInvocation *invocation;
1018
1019         invocation = (GDBusMethodInvocation *)g_hash_table_lookup(req_table,
1020                         (gpointer)req_key);
1021         if (invocation == NULL) {
1022                 ERR("no such request id");
1023                 return -1;
1024         }
1025
1026         g_dbus_method_invocation_return_value(invocation, result);
1027         g_hash_table_remove(req_table, (gpointer)req_key);
1028
1029         return 0;
1030 }
1031
1032 static const GDBusInterfaceVTable interface_vtable =
1033 {
1034         __handle_method_call,
1035         NULL,
1036         NULL,
1037 };
1038
1039 static void __on_bus_acquired(GDBusConnection *connection, const gchar *name,
1040                 gpointer user_data)
1041 {
1042         GError *err = NULL;
1043
1044         DBG("on bus acquired");
1045
1046         reg_id = g_dbus_connection_register_object(connection,
1047                         COMM_PKGMGR_DBUS_OBJECT_PATH,
1048                         instropection_data->interfaces[0],
1049                         &interface_vtable, NULL, NULL, &err);
1050
1051         if (reg_id == 0) {
1052                 ERR("failed to register object: %s", err->message);
1053                 g_error_free(err);
1054         }
1055 }
1056
1057 static void __on_name_acquired(GDBusConnection *connection, const gchar *name,
1058                 gpointer user_data)
1059 {
1060         DBG("on name acquired: %s", name);
1061 }
1062
1063 static void __on_name_lost(GDBusConnection *connection, const gchar *name,
1064                 gpointer user_data)
1065 {
1066         DBG("on name lost: %s", name);
1067 }
1068
1069 int __init_request_handler(void)
1070 {
1071         instropection_data = g_dbus_node_info_new_for_xml(instropection_xml, NULL);
1072
1073         owner_id = g_bus_own_name(G_BUS_TYPE_SYSTEM, COMM_PKGMGR_DBUS_SERVICE,
1074                         G_BUS_NAME_OWNER_FLAGS_NONE, __on_bus_acquired,
1075                         __on_name_acquired, __on_name_lost, NULL, NULL);
1076
1077         req_table = g_hash_table_new_full(g_str_hash, g_str_equal,
1078                         free, NULL);
1079         if (req_table == NULL)
1080                 return -1;
1081
1082         return 0;
1083 }
1084
1085 void __fini_request_handler(void)
1086 {
1087         g_hash_table_destroy(req_table);
1088         g_bus_unown_name(owner_id);
1089         g_dbus_node_info_unref(instropection_data);
1090 }