Clean up repository, remove warnings
[platform/core/appfw/slp-pkgmgr.git] / server / src / pkgmgr-server.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 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <ctype.h>
27 #include <unistd.h>
28 #include <pwd.h>
29 #include <sys/types.h>
30 #include <sys/wait.h>
31 #include <sys/stat.h>
32 #include <dirent.h>
33 #include <sys/types.h>
34 #include <fcntl.h>
35 #include <signal.h>
36
37 #include <glib.h>
38
39 #include <pkgmgr-info.h>
40 #include <pkgmgr/pkgmgr_parser.h>
41 #include <cynara-client.h>
42 #include <tzplatform_config.h>
43
44 #include "pkgmgr_installer.h"
45 #include "comm_pkg_mgr_server.h"
46 #include "pkgmgr-server.h"
47 #include "pm-queue.h"
48 #include "comm_config.h"
49 #include "package-manager.h"
50
51 #define BUFMAX 128
52 #define NO_MATCHING_FILE 11
53
54 #define OWNER_ROOT 0
55 #define GLOBAL_USER tzplatform_getuid(TZ_SYS_GLOBALAPP_USER)
56
57 static int backend_flag = 0;    /* 0 means that backend process is not running */
58
59 typedef struct  {
60         char **env;
61         uid_t uid;
62         gid_t gid;
63 } user_ctx;
64
65
66 /*
67 8 bit value to represent maximum 8 backends.
68 Each bit position corresponds to a queue slot which
69 is dynamically determined.
70 */
71 char backend_busy = 0;
72 /*
73 8 bit value to represent quiet mode operation for maximum 8 backends
74 1->quiet 0->non-quiet
75 Each bit position corresponds to a queue slot which
76 is dynamically determined.
77 */
78 char backend_mode = 63; /*00111111*/
79 extern int num_of_backends;
80
81 struct signal_info_t {
82         pid_t pid;
83         int status;
84 };
85
86 static int pipe_sig[2];
87 static GIOChannel *pipe_io;
88 static guint pipe_wid;
89
90 backend_info *begin;
91 extern queue_info_map *start;
92 extern int entries;
93 static cynara *p_cynara;
94
95 GMainLoop *mainloop = NULL;
96
97
98 /* operation_type */
99 typedef enum {
100         OPERATION_INSTALL = 0,
101         OPERATION_UNINSTALL,
102         OPERATION_ACTIVATE,
103         OPERATION_REINSTALL,
104         OPERATION_MAX
105 } OPERATION_TYPE;
106
107 typedef enum {
108         PMSVC_ALL_APP = 0,
109         PMSVC_UI_APP,
110         PMSVC_SVC_APP
111 }pkgmgr_svc_app_component;
112
113 static int __check_backend_status_for_exit(void);
114 static int __check_queue_status_for_exit(void);
115 static int __is_backend_busy(int position);
116 static void __set_backend_busy(int position);
117 static void __set_backend_free(int position);
118 static void __set_backend_mode(int position);
119 static void __unset_backend_mode(int position);
120 static void sighandler(int signo);
121 static int __get_position_from_pkg_type(char *pkgtype);
122 static int __is_efl_tpk_app(char *pkgpath);
123 static int __xsystem(const char *argv[]);
124
125 gboolean queue_job(void *data);
126 gboolean exit_server(void *data);
127
128 /* To check whether a particular backend is free/busy*/
129 static int __is_backend_busy(int position)
130 {
131         return backend_busy & 1<<position;
132 }
133 /*To set a particular backend as busy*/
134 static void __set_backend_busy(int position)
135 {
136         backend_busy = backend_busy | 1<<position;
137 }
138 /*To set a particular backend as free */
139 static void __set_backend_free(int position)
140 {
141         backend_busy = backend_busy & ~(1<<position);
142 }
143 /*To set a particular backend mode as quiet*/
144 static void __set_backend_mode(int position)
145 {
146         backend_mode = backend_mode | 1<<position;
147 }
148 /*To unset a particular backend mode */
149 static void __unset_backend_mode(int position)
150 {
151         backend_mode = backend_mode & ~(1<<position);
152 }
153
154 static int __is_global(uid_t uid)
155 {
156         return (uid == OWNER_ROOT || uid == GLOBAL_USER) ? 1 : 0;
157 }
158
159 static const char *__get_recovery_file_path(uid_t uid)
160 {
161         const char *path;
162
163         if (!__is_global(uid))
164                 tzplatform_set_user(uid);
165
166         path = tzplatform_getenv(__is_global(uid)
167                         ? TZ_SYS_RW_PACKAGES : TZ_USER_PACKAGES);
168
169         tzplatform_reset_user();
170
171         return path;
172 }
173
174 static void __set_recovery_mode(uid_t uid, char *pkgid, char *pkg_type)
175 {
176         char recovery_file[MAX_PKG_NAME_LEN] = { 0, };
177         char buffer[MAX_PKG_NAME_LEN] = { 0 };
178         char *pkgid_tmp = NULL;
179         FILE *rev_file = NULL;
180
181         if (pkgid == NULL) {
182                 DBG("pkgid is null\n");
183                 return;
184         }
185
186         /*if pkgid has a "/"charactor, that is a path name for installation, then extract pkgid from absolute path*/
187         if (strstr(pkgid, "/")) {
188                 pkgid_tmp = strrchr(pkgid, '/') + 1;
189                 if (pkgid_tmp == NULL) {
190                         DBG("pkgid_tmp[%s] is null\n", pkgid);
191                         return;
192                 }
193                 snprintf(recovery_file, sizeof(recovery_file), "%s/%s", __get_recovery_file_path(uid), pkgid_tmp);
194         } else {
195                 snprintf(recovery_file, sizeof(recovery_file), "%s/%s", __get_recovery_file_path(uid), pkgid);
196         }
197
198         rev_file = fopen(recovery_file, "w");
199         if (rev_file== NULL) {
200                 DBG("rev_file[%s] is null\n", recovery_file);
201                 return;
202         }
203
204         snprintf(buffer, MAX_PKG_NAME_LEN, "pkgid : %s\n", pkgid);
205         fwrite(buffer, sizeof(char), strlen(buffer), rev_file);
206
207         fclose(rev_file);
208 }
209
210 static void __unset_recovery_mode(uid_t uid, char *pkgid, char *pkg_type)
211 {
212         int ret = -1;
213         char recovery_file[MAX_PKG_NAME_LEN] = { 0, };
214         char *pkgid_tmp = NULL;
215
216         if (pkgid == NULL) {
217                 DBG("pkgid is null\n");
218                 return;
219         }
220
221         /*if pkgid has a "/"charactor, that is a path name for installation, then extract pkgid from absolute path*/
222         if (strstr(pkgid, "/")) {
223                 pkgid_tmp = strrchr(pkgid, '/') + 1;
224                 if (pkgid_tmp == NULL) {
225                         DBG("pkgid_tmp[%s] is null\n", pkgid);
226                         return;
227                 }
228                 snprintf(recovery_file, sizeof(recovery_file), "%s/%s", __get_recovery_file_path(uid), pkgid_tmp);
229         } else {
230                 snprintf(recovery_file, sizeof(recovery_file), "%s/%s", __get_recovery_file_path(uid), pkgid);
231         }
232
233         ret = remove(recovery_file);
234         if (ret < 0)
235                 DBG("remove recovery_file[%s] fail\n", recovery_file);
236 }
237
238 #define PRIVILEGE_PACKAGEMANAGER_ADMIN "http://tizen.org/privilege/packagemanager.admin"
239 #define PRIVILEGE_PACKAGEMANAGER_INFO  "http://tizen.org/privilege/packagemanager.info"
240 #define PRIVILEGE_PACKAGEMANAGER_NONE  "NONE"
241
242 static const char *__convert_req_type_to_privilege(int req_type)
243 {
244         switch (req_type) {
245         case COMM_REQ_TO_INSTALLER:
246         case COMM_REQ_TO_ACTIVATOR:
247         case COMM_REQ_TO_CLEARER:
248         case COMM_REQ_TO_MOVER:
249         case COMM_REQ_KILL_APP:
250         case COMM_REQ_CLEAR_CACHE_DIR:
251                 return PRIVILEGE_PACKAGEMANAGER_ADMIN;
252         case COMM_REQ_GET_SIZE:
253         case COMM_REQ_CHECK_APP:
254                 return PRIVILEGE_PACKAGEMANAGER_INFO;
255         case COMM_REQ_CANCEL:
256         default:
257                 return PRIVILEGE_PACKAGEMANAGER_NONE;
258         }
259 }
260
261 static int __check_privilege_by_cynara(const char *client, const char *session, const char *user, int req_type)
262 {
263         int ret;
264         const char *privilege;
265         char buf[BUFMAX] = {0, };
266
267         privilege = __convert_req_type_to_privilege(req_type);
268         if (!strcmp(privilege, PRIVILEGE_PACKAGEMANAGER_NONE))
269                 return 0;
270
271         ret = cynara_check(p_cynara, client, session, user, privilege);
272         switch (ret) {
273         case CYNARA_API_ACCESS_ALLOWED:
274                 DBG("%s(%s) from user %s privilege %s allowed", client, session, user, privilege);
275                 return 0;
276         case CYNARA_API_ACCESS_DENIED:
277                 ERR("%s(%s) from user %s privilege %s denied", client, session, user, privilege);
278                 return -1;
279         default:
280                 cynara_strerror(ret, buf, BUFMAX);
281                 ERR("cynara_check failed: %s", buf);
282                 return -1;
283         }
284 }
285
286 static int __get_position_from_pkg_type(char *pkgtype)
287 {
288         int i = 0;
289         queue_info_map *ptr;
290         ptr = start;
291         for(i = 0; i < entries; i++)
292         {
293                 if (!strncmp(ptr->pkgtype, pkgtype, MAX_PKG_TYPE_LEN))
294                         return ptr->queue_slot;
295                 else
296                         ptr++;
297
298         }
299         return -1;
300 }
301
302 static int __xsystem(const char *argv[])
303 {
304         int err = 0;
305         int status = 0;
306         pid_t pid;
307
308         pid = fork();
309
310         switch (pid) {
311         case -1:
312                 DBG("fork() failed");
313                 return -1;
314         case 0:
315                 if (execvp(argv[0], (char *const *)argv) == -1) {
316                         DBG("execvp() failed");
317                 }
318                 _exit(100);
319         default:
320                 /* parent */
321                 do {
322                         err = waitpid(pid, &status, WUNTRACED | WCONTINUED);
323                         if (err == -1) {
324                                 DBG("waitpid failed\n");
325                                 return -1;
326                         }
327                 } while (!WIFEXITED(status) && !WIFSIGNALED(status));
328                 break;
329         }
330         if (WIFEXITED(status))
331                 return WEXITSTATUS(status);
332         else
333                 return -1;
334 }
335
336 static int __is_efl_tpk_app(char *pkgid)
337 {
338         int ret = 0;
339         char *type = NULL;
340         const char *unzip_argv[] = { "/usr/bin/unzip", "-j", pkgid, "usr/share/packages/*", "-d", "/tmp/efltpk-unzip", NULL };
341         const char *unzip_opt_argv[] = { "/usr/bin/unzip", "-j", pkgid, "opt/share/packages/*", "-d", "/tmp/efltpk-unzip", NULL };
342         const char *delete_argv[] = { "/bin/rm", "-rf", "/tmp/efltpk-unzip", NULL };
343         pkgmgrinfo_pkginfo_h handle;
344         /*Check for uninstall case. If we fail to get handle then request is for installation*/
345         ret = pkgmgrinfo_pkginfo_get_pkginfo(pkgid, &handle);
346         if (ret == PMINFO_R_OK) {
347                 ret = pkgmgrinfo_pkginfo_get_type(handle, &type);
348                 if (ret != PMINFO_R_OK) {
349                         DBG("Failed to get package type\n");
350                         pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
351                         return -1;
352                 }
353                 if (strcmp(type, "efltpk") == 0) {
354                         pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
355                         return 1;
356                 } else {
357                         pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
358                         return 0;
359                 }
360         }
361         /*Install request*/
362         if (strstr(pkgid, ".tpk") == NULL) {
363                 DBG("TPK package");
364                 return 0;
365         }
366         __xsystem(delete_argv);
367         ret = mkdir("/tmp/efltpk-unzip", 0755);
368         if (ret != 0) {
369                 DBG("Failed to create temporary directory to unzip tpk package\n");
370                 return -1;
371         }
372         /*In case of installation request, pkgid contains the pkgpath*/
373         ret = __xsystem(unzip_argv);
374         if (ret) {
375                 ret = __xsystem(unzip_opt_argv);
376                 if (ret) {
377                         DBG("Unzip of tpk package failed. error:%d\n", ret);
378                         if (ret == NO_MATCHING_FILE) /*no matching file found*/
379                                 ret = 0;
380                         else
381                                 ret = -1;
382                         goto err;
383                 } else
384                         ret = 1;
385         } else
386                 ret = 1;
387 err:
388         __xsystem(delete_argv);
389         return ret;
390 }
391
392 static void send_fail_signal(char *pname, char *ptype, char *args)
393 {
394         DBG("send_fail_signal start\n");
395         gboolean ret_parse;
396         gint argcp;
397         gchar **argvp;
398         GError *gerr = NULL;
399         pkgmgr_installer *pi;
400         pi = pkgmgr_installer_new();
401         if (!pi) {
402                 DBG("Failure in creating the pkgmgr_installer object");
403                 return;
404         }
405         ret_parse = g_shell_parse_argv(args,
406                                        &argcp, &argvp, &gerr);
407         if (FALSE == ret_parse) {
408                 DBG("Failed to split args: %s", args);
409                 DBG("messsage: %s", gerr->message);
410                 pkgmgr_installer_free(pi);
411                 return;
412         }
413
414         pkgmgr_installer_receive_request(pi, argcp, argvp);
415         pkgmgr_installer_send_signal(pi, ptype, pname, "end", "fail");
416         pkgmgr_installer_free(pi);
417         return;
418 }
419
420 static gboolean pipe_io_handler(GIOChannel *io, GIOCondition cond, gpointer data)
421 {
422         int x;
423         GError *err = NULL;
424         GIOStatus s;
425         gsize len;
426         struct signal_info_t info;
427         backend_info *ptr = begin;
428
429         s = g_io_channel_read_chars(io, (gchar *)&info, sizeof(struct signal_info_t), &len, &err);
430         if (s != G_IO_STATUS_NORMAL) {
431                 ERR("Signal pipe read failed: %s", err->message);
432                 g_error_free(err);
433                 return TRUE;
434         }
435
436         for (x = 0; x < num_of_backends; x++, ptr++) {
437                 if (ptr && ptr->pid == info.pid)
438                         break;
439         }
440
441         if (x == num_of_backends) {
442                 ERR("Unknown child exit");
443                 return -1;
444         }
445
446         __set_backend_free(x);
447         __set_backend_mode(x);
448         __unset_recovery_mode(ptr->uid, ptr->pkgid, ptr->pkgtype);
449         if (WIFSIGNALED(info.status) || WEXITSTATUS(info.status)) {
450                 send_fail_signal(ptr->pkgid, ptr->pkgtype, ptr->args);
451                 DBG("backend[%s] exit with error", ptr->pkgtype);
452         } else {
453                 DBG("backend[%s] exit", ptr->pkgtype);
454         }
455
456         g_idle_add(queue_job, NULL);
457
458         return TRUE;
459 }
460
461 static int __init_backend_info(void)
462 {
463         backend_info *ptr;
464
465         /*Allocate memory for holding pid, pkgtype and pkgid*/
466         ptr = (backend_info*)calloc(num_of_backends, sizeof(backend_info));
467         if (ptr == NULL) {
468                 DBG("Malloc Failed\n");
469                 return -1;
470         }
471         begin = ptr;
472
473         if (pipe(pipe_sig)) {
474                 ERR("create pipe failed");
475                 return -1;
476         }
477
478         pipe_io = g_io_channel_unix_new(pipe_sig[0]);
479         g_io_channel_set_encoding(pipe_io, NULL, NULL);
480         g_io_channel_set_buffered(pipe_io, FALSE);
481         pipe_wid = g_io_add_watch(pipe_io, G_IO_IN, pipe_io_handler, NULL);
482
483         return 0;
484 }
485
486 static void __fini_backend_info(void)
487 {
488         g_source_remove(pipe_wid);
489         g_io_channel_unref(pipe_io);
490         close(pipe_sig[0]);
491         close(pipe_sig[1]);
492
493         /*Free backend info */
494         free(begin);
495 }
496
497 static void sighandler(int signo)
498 {
499         struct signal_info_t info;
500
501         info.pid = waitpid(-1, &info.status, WNOHANG);
502         if (write(pipe_sig[1], &info, sizeof(struct signal_info_t)) < 0)
503                 ERR("failed to write result: %s", strerror(errno));
504 }
505
506 static int __register_signal_handler(void)
507 {
508         static int sig_reg = 0;
509         struct sigaction act;
510
511         if (sig_reg)
512                 return 0;
513
514         act.sa_handler = sighandler;
515         sigemptyset(&act.sa_mask);
516         act.sa_flags = SA_NOCLDSTOP;
517         if (sigaction(SIGCHLD, &act, NULL) < 0) {
518                 ERR("signal: SIGCHLD failed\n");
519                 return -1;
520         }
521
522         g_timeout_add_seconds(2, exit_server, NULL);
523
524         sig_reg = 1;
525         return 0;
526 }
527
528 void req_cb(void *cb_data, uid_t uid, const char *req_id, const int req_type,
529             const char *pkg_type, const char *pkgid, const char *args,
530             const char *client, const char *session, const char *user, int *ret)
531 {
532         int p;
533
534         DBG(">> in callback >> Got request: [%s] [%d] [%s] [%s] [%s] [%s] [%s] [%s]",
535             req_id, req_type, pkg_type, pkgid, args, client, session, user);
536
537         pm_dbus_msg *item = calloc(1, sizeof(pm_dbus_msg));
538         memset(item, 0x00, sizeof(pm_dbus_msg));
539
540         strncpy(item->req_id, req_id, sizeof(item->req_id) - 1);
541         item->req_type = req_type;
542         strncpy(item->pkg_type, pkg_type, sizeof(item->pkg_type) - 1);
543         strncpy(item->pkgid, pkgid, sizeof(item->pkgid) - 1);
544         strncpy(item->args, args, sizeof(item->args) - 1);
545         item->uid = uid;
546         /* uid equals to GLOBALUSER means that the installation or action is made at Global level.
547          * At this time, we are not able to check the credentials of this dbus message (due to gdbus API to implement the pkgmgr-server)
548          * So we cannot check if the user that makes request has permisssion to do it.
549          * Note theses CAPI could be used by deamon (user is root or system user) or web/native API framework (user id is one of regular users)
550          * In consequence a bug is filed :
551          *
552          * Logic has to be implmemented:
553          * RUID means the id of the user that make the request (retreived from credential of the message)
554          * UID is the uid in argument of the request
555          *
556          * if RUID == UID & UID is regular user == TRUE ==> Granted
557          * if UID == GLOBAL_USER & RUID is ADMIN == TRUE ==> Granted
558          * if RUID == (ROOT or System USER) & UID is Regular USER ==> Granted
559          * if UID != Regular USER & UID != GLOBAL USER  == TRUE ==> NOT GRANTED
560          * if RUID == Regular USER & UID != RUID == True ==> NOT GRANTED
561          *  */
562
563         if (__register_signal_handler()) {
564                 ERR("failed to register signal handler");
565                 *ret = COMM_RET_ERROR;
566                 goto err;
567         }
568         g_idle_add(queue_job, NULL);
569
570         DBG("req_type=(%d) backend_flag=(%d)\n", req_type, backend_flag);
571
572         if (__check_privilege_by_cynara(client, session, user, item->req_type)) {
573                 *ret = PKGMGR_R_EPRIV;
574                 goto err;
575         }
576
577         switch (item->req_type) {
578         case COMM_REQ_TO_INSTALLER:
579                 /* quiet mode */
580                 if (_pm_queue_push(item)) {
581                         ERR("failed to push queue item");
582                         *ret = COMM_RET_ERROR;
583                         goto err;
584                 }
585                 p = __get_position_from_pkg_type(item->pkg_type);
586                 __set_backend_mode(p);
587                 /* Free resource */
588                 free(item);
589                 *ret = COMM_RET_OK;
590                 break;
591         case COMM_REQ_TO_ACTIVATOR:
592                 /* In case of activate, there is no popup */
593                 if (_pm_queue_push(item)) {
594                         ERR("failed to push queue item");
595                         *ret = COMM_RET_ERROR;
596                         goto err;
597                 }
598                 p = __get_position_from_pkg_type(item->pkg_type);
599                 __set_backend_mode(p);
600                 /* Free resource */
601                 free(item);
602
603                 *ret = COMM_RET_OK;
604                 break;
605         case COMM_REQ_TO_CLEARER:
606                 /* In case of clearer, there is no popup */
607                 if (_pm_queue_push(item)) {
608                         ERR("failed to push queue item");
609                         *ret = COMM_RET_ERROR;
610                         goto err;
611                 }
612                 p = __get_position_from_pkg_type(item->pkg_type);
613                 /*the backend shows the success/failure popup
614                 so this request is non quiet*/
615                 __unset_backend_mode(p);
616                 /* Free resource */
617                 free(item);
618
619                 *ret = COMM_RET_OK;
620                 break;
621         case COMM_REQ_TO_MOVER:
622                 /* In case of mover, there is no popup */
623                 if (_pm_queue_push(item)) {
624                         ERR("failed to push queue item");
625                         *ret = COMM_RET_ERROR;
626                         goto err;
627                 }
628                 p = __get_position_from_pkg_type(item->pkg_type);
629                 /*the backend shows the success/failure popup
630                 so this request is non quiet*/
631                 __unset_backend_mode(p);
632                 /* Free resource */
633                 free(item);
634                 *ret = COMM_RET_OK;
635                 break;
636         case COMM_REQ_CANCEL:
637                 _pm_queue_delete(item);
638                 p = __get_position_from_pkg_type(item->pkg_type);
639                 __unset_backend_mode(p);
640                 free(item);
641                 *ret = COMM_RET_OK;
642                 break;
643         case COMM_REQ_GET_SIZE:
644                 if (_pm_queue_push(item)) {
645                         ERR("failed to push queue item");
646                         *ret = COMM_RET_ERROR;
647                         goto err;
648                 }
649                 p = __get_position_from_pkg_type(item->pkg_type);
650                 __set_backend_mode(p);
651                 /* Free resource */
652                 free(item);
653                 *ret = COMM_RET_OK;
654                 break;
655
656         case COMM_REQ_CHECK_APP:
657         case COMM_REQ_KILL_APP:
658                 /* In case of activate, there is no popup */
659                 if (_pm_queue_push(item)) {
660                         ERR("failed to push queue item");
661                         *ret = COMM_RET_ERROR;
662                         goto err;
663                 }
664                 p = __get_position_from_pkg_type(item->pkg_type);
665                 __set_backend_mode(p);
666                 /* Free resource */
667                 free(item);
668
669                 *ret = COMM_RET_OK;
670                 break;
671         case COMM_REQ_CLEAR_CACHE_DIR:
672                 if (_pm_queue_push(item)) {
673                         ERR("failed to push queue item");
674                         *ret = COMM_RET_ERROR;
675                         goto err;
676                 }
677                 p = __get_position_from_pkg_type(item->pkg_type);
678                 __set_backend_mode(p);
679
680                 *ret = PKGMGR_R_OK;
681                 break;
682
683         default:
684                 DBG("Check your request..\n");
685                 *ret = COMM_RET_ERROR;
686                 break;
687         }
688 err:
689         if (*ret != COMM_RET_OK) {
690                 DBG("Failed to handle request %s %s\n",item->pkg_type, item->pkgid);
691                 pkgmgr_installer *pi;
692                 gboolean ret_parse;
693                 gint argcp;
694                 gchar **argvp;
695                 GError *gerr = NULL;
696
697                 pi = pkgmgr_installer_new();
698                 if (!pi) {
699                         DBG("Failure in creating the pkgmgr_installer object");
700                         free(item);
701                         return;
702                 }
703
704                 ret_parse = g_shell_parse_argv(args, &argcp, &argvp, &gerr);
705                 if (FALSE == ret_parse) {
706                         DBG("Failed to split args: %s", args);
707                         DBG("messsage: %s", gerr->message);
708                         pkgmgr_installer_free(pi);
709                         free(item);
710                         return;
711                 }
712
713                 pkgmgr_installer_receive_request(pi, argcp, argvp);
714
715                 pkgmgr_installer_send_signal(pi, item->pkg_type,
716                                              item->pkgid, "end",
717                                              "fail");
718
719                 pkgmgr_installer_free(pi);
720
721                 free(item);
722         }
723         return;
724 }
725 static int __check_backend_status_for_exit(void)
726 {
727         int i = 0;
728         for(i = 0; i < num_of_backends; i++)
729         {
730                 if (!__is_backend_busy(i))
731                         continue;
732                 else
733                         return 0;
734         }
735         return 1;
736 }
737
738 static int __check_queue_status_for_exit(void)
739 {
740         pm_queue_data *head[MAX_QUEUE_NUM] = {NULL,};
741         queue_info_map *ptr = NULL;
742         ptr = start;
743         int i = 0;
744         int c = 0;
745         int slot = -1;
746         for(i = 0; i < entries; i++)
747         {
748                 if (ptr->queue_slot <= slot) {
749                         ptr++;
750                         continue;
751                 }
752                 else {
753                         head[c] = ptr->head;
754                         slot = ptr->queue_slot;
755                         c++;
756                         ptr++;
757                 }
758         }
759         for(i = 0; i < num_of_backends; i++)
760         {
761                 if (!head[i])
762                         continue;
763                 else
764                         return 0;
765         }
766         return 1;
767 }
768
769 gboolean exit_server(void *data)
770 {
771         DBG("exit_server Start\n");
772         if (__check_backend_status_for_exit() &&
773                         __check_queue_status_for_exit()) {
774                 if (!getenv("PMS_STANDALONE")) {
775                         g_main_loop_quit(mainloop);
776                         return FALSE;
777                 }
778         }
779         return TRUE;
780 }
781
782 static int __pkgcmd_read_proc(const char *path, char *buf, int size)
783 {
784         int fd;
785         int ret;
786         if (buf == NULL || path == NULL)
787                 return -1;
788         fd = open(path, O_RDONLY);
789         if (fd < 0)
790                 return -1;
791         ret = read(fd, buf, size - 1);
792         if (ret <= 0) {
793                 close(fd);
794                 return -1;
795         } else
796                 buf[ret] = 0;
797         close(fd);
798         return ret;
799 }
800
801 static int __pkgcmd_find_pid_by_cmdline(const char *dname,
802                         const char *cmdline, const char *apppath)
803 {
804         int pid = 0;
805
806         if (strcmp(cmdline, apppath) == 0) {
807                 pid = atoi(dname);
808                 if (pid != getpgid(pid))
809                         pid = 0;
810         }
811         return pid;
812 }
813
814 static int __pkgcmd_proc_iter_kill_cmdline(const char *apppath, int option)
815 {
816         DIR *dp;
817         struct dirent *dentry;
818         int pid;
819         int ret;
820         char buf[1024] = {'\0'};
821         int pgid;
822
823         dp = opendir("/proc");
824         if (dp == NULL) {
825                 return -1;
826         }
827
828         while ((dentry = readdir(dp)) != NULL) {
829                 if (!isdigit(dentry->d_name[0]))
830                         continue;
831
832                 snprintf(buf, sizeof(buf), "/proc/%s/cmdline", dentry->d_name);
833                 ret = __pkgcmd_read_proc(buf, buf, sizeof(buf));
834                 if (ret <= 0)
835                         continue;
836
837                 pid = __pkgcmd_find_pid_by_cmdline(dentry->d_name, buf, apppath);
838                 if (pid > 0) {
839                         if (option == 0) {
840                                 closedir(dp);
841                                 return pid;
842                         }
843                         pgid = getpgid(pid);
844                         if (pgid <= 1) {
845                                 closedir(dp);
846                                 return -1;
847                         }
848                         if (killpg(pgid, SIGKILL) < 0) {
849                                 closedir(dp);
850                                 return -1;
851                         }
852                         closedir(dp);
853                         return pid;
854                 }
855         }
856         closedir(dp);
857         return 0;
858 }
859
860 static void __make_pid_info_file(char *req_key, int pid)
861 {
862         FILE* file;
863         int fd;
864         char buf[MAX_PKG_TYPE_LEN] = {0};
865         char info_file[PATH_MAX] = {'\0'};
866
867         if(req_key == NULL)
868                 return;
869
870         snprintf(info_file, PATH_MAX, "/tmp/%s", req_key);
871
872         DBG("info_path(%s)", info_file);
873         file = fopen(info_file, "w");
874         if (file == NULL) {
875                 ERR("Couldn't open the file(%s)", info_file);
876                 return;
877         }
878
879         snprintf(buf, MAX_PKG_TYPE_LEN, "%d\n", pid);
880         fwrite(buf, 1, strlen(buf), file);
881
882         fflush(file);
883         fd = fileno(file);
884         fsync(fd);
885         fclose(file);
886 }
887
888 static int __pkgcmd_app_cb(const pkgmgrinfo_appinfo_h handle, void *user_data)
889 {
890         char *pkgid;
891         char *exec;
892         int ret;
893         int pid = -1;
894
895         if (handle == NULL) {
896                 perror("appinfo handle is NULL\n");
897                 exit(1);
898         }
899         ret = pkgmgrinfo_appinfo_get_exec(handle, &exec);
900         if (ret) {
901                 perror("Failed to get app exec path\n");
902                 exit(1);
903         }
904         ret = pkgmgrinfo_appinfo_get_pkgid(handle, &pkgid);
905         if (ret) {
906                 perror("Failed to get pkgid\n");
907                 exit(1);
908         }
909
910         if (strcmp(user_data, "kill") == 0)
911                 pid = __pkgcmd_proc_iter_kill_cmdline(exec, 1);
912         else if(strcmp(user_data, "check") == 0)
913                 pid = __pkgcmd_proc_iter_kill_cmdline(exec, 0);
914
915         __make_pid_info_file(pkgid, pid);
916
917         return 0;
918 }
919
920 void free_user_context(user_ctx* ctx)
921 {
922         char **env = NULL;
923         int i = 0;
924         if (!ctx)
925                 return;
926         env = ctx->env;
927         //env variable ends by NULL element
928         while (env[i]) {
929                 free(env[i]);
930                 i++;
931         }
932         free(env);
933         env = NULL;
934         free(ctx);
935 }
936
937 int set_environement(user_ctx *ctx)
938 {
939         int i = 0;
940         int res = 0;
941         char **env = NULL;
942         if (!ctx)
943                 return -1;;
944         if (setgid(ctx->gid)) {
945                 ERR("setgid failed: %d", errno);
946                 return -1;
947         }
948         if (setuid(ctx->uid)) {
949                 ERR("setuid failed: %d", errno);
950                 return -1;
951         }
952         env = ctx->env;
953         //env variable ends by NULL element
954         while (env[i]) {
955                 if (putenv(env[i]) != 0)
956                         res = -1;
957                 i++;
958         }
959         return res;
960 }
961
962 user_ctx* get_user_context(uid_t uid)
963 {
964         /* we can use getpwnam because this is used only after a
965          * fork and just before an execv
966          * No concurrencial call can corrupt the data
967          * returned by getpwuid
968          */
969         user_ctx *context_res;
970         char **env = NULL;
971         struct passwd * pwd;
972         int len;
973         int ret = 0;
974
975         pwd = getpwuid(uid);
976         if (!pwd)
977                 return NULL;
978
979         do {
980                 context_res = (user_ctx *)malloc(sizeof(user_ctx));
981                 if (!context_res) {
982                         ret = -1;
983                         break;
984                 }
985                 env = (char**)malloc(3* sizeof(char *));
986                 if (!env) {
987                         ret = -1;
988                         break;
989                 }
990                 // Build environment context
991                 len = snprintf(NULL,0, "HOME=%s", pwd->pw_dir);
992                 env[0] = (char*)malloc((len + 1)* sizeof(char));
993                 if(env[0] == NULL) {
994                         ret = -1;
995                         break;
996                 }
997                 sprintf(env[0], "HOME=%s", pwd->pw_dir);
998                 len = snprintf(NULL,0, "USER=%s", pwd->pw_name);
999                 env[1] = (char*)malloc((len + 1)* sizeof(char));
1000                 if(env[1] == NULL) {
1001                         ret = -1;
1002                         break;
1003                 }
1004
1005                 sprintf(env[1], "USER=%s", pwd->pw_name);
1006                 env[2] = NULL;
1007         } while (0);
1008
1009         if (ret == -1) {
1010                 free(context_res);
1011                 context_res = NULL;
1012                 int i = 0;
1013                 //env variable ends by NULL element
1014                 while (env[i]) {
1015                         free(env[i]);
1016                         i++;
1017                 }
1018                 free(env);
1019                 env = NULL;
1020         } else {
1021                 context_res->env = env;
1022                 context_res->uid = uid;
1023                 context_res->gid = pwd->pw_gid;
1024         }
1025         return context_res;
1026 }
1027
1028 static char **__generate_argv(const char *args)
1029 {
1030         /* Create args vector
1031          * req_id + pkgid + args
1032          *
1033          * vector size = # of args +
1034          *(req_id + pkgid + NULL termination = 3)
1035          * Last value must be NULL for execv.
1036          */
1037         gboolean ret_parse;
1038         gint argcp;
1039         gchar **argvp;
1040         GError *gerr = NULL;
1041         ret_parse = g_shell_parse_argv(args,
1042                         &argcp, &argvp, &gerr);
1043         if (FALSE == ret_parse) {
1044                 DBG("Failed to split args: %s", args);
1045                 DBG("messsage: %s", gerr->message);
1046                 exit(1);
1047         }
1048
1049         /* Setup argument !!! */
1050         /*char **args_vector =
1051           calloc(argcp + 4, sizeof(char *)); */
1052         char **args_vector = calloc(argcp + 1, sizeof(char *));
1053         if (args_vector == NULL) {
1054                 ERR("Out of memory");
1055                 exit(1);
1056         }
1057         /*args_vector[0] = strdup(backend_cmd);
1058           args_vector[1] = strdup(item->req_id);
1059           args_vector[2] = strdup(item->pkgid); */
1060         int arg_idx;
1061         for (arg_idx = 0; arg_idx < argcp; arg_idx++) {
1062                 /* args_vector[arg_idx+3] = argvp[arg_idx]; */
1063                 args_vector[arg_idx] = argvp[arg_idx];
1064         }
1065
1066         /* dbg */
1067         /*for(arg_idx = 0; arg_idx < argcp+3; arg_idx++) { */
1068         for (arg_idx = 0; arg_idx < argcp + 1; arg_idx++) {
1069                 DBG(">>>>>> args_vector[%d]=%s",
1070                                 arg_idx, args_vector[arg_idx]);
1071         }
1072
1073         return args_vector;
1074 }
1075
1076 static void __exec_with_arg_vector(const char *cmd, char **argv, uid_t uid)
1077 {
1078         user_ctx* user_context = get_user_context(uid);
1079         if(!user_context) {
1080                 DBG("Failed to getenv for the user : %d", uid);
1081                 exit(1);
1082         }
1083         if(set_environement(user_context)){
1084                 DBG("Failed to set env for the user : %d", uid);
1085                 exit(1);
1086         }
1087         free_user_context(user_context);
1088
1089         /* Execute backend !!! */
1090         int ret = execv(cmd, argv);
1091
1092         /* Code below: exec failure. Should not be happened! */
1093         DBG(">>>>>> OOPS 2!!!");
1094
1095         /* g_strfreev(args_vector); *//* FIXME: causes error */
1096
1097         if (ret == -1) {
1098                 perror("fail to exec");
1099                 exit(1);
1100         }
1101 }
1102
1103 gboolean queue_job(void *data)
1104 {
1105         pm_dbus_msg *item = NULL;
1106         backend_info *ptr;
1107         int x;
1108         int ret;
1109         char *backend_cmd = NULL;
1110
1111         /* Pop a job from queue */
1112         for (x = 0, ptr = begin; x < num_of_backends; x++, ptr++) {
1113                 if (__is_backend_busy(x))
1114                         continue;
1115
1116                 item = _pm_queue_pop(x);
1117                 if (item && item->req_type != -1)
1118                         break;
1119                 free(item);
1120         }
1121
1122         /* all backend messages queue are empty or busy */
1123         if (x == num_of_backends)
1124                 return FALSE;
1125
1126         __set_backend_busy(x);
1127         __set_recovery_mode(item->uid, item->pkgid, item->pkg_type);
1128
1129         /* fork */
1130         _save_queue_status(item, "processing");
1131         DBG("saved queue status. Now try fork()");
1132         /*save pkg type and pkg name for future*/
1133         strncpy(ptr->pkgtype, item->pkg_type, MAX_PKG_TYPE_LEN-1);
1134         strncpy(ptr->pkgid, item->pkgid, MAX_PKG_NAME_LEN-1);
1135         strncpy(ptr->args, item->args, MAX_PKG_ARGS_LEN-1);
1136         ptr->uid = item->uid;
1137         ptr->pid = fork();
1138         DBG("child forked [%d] for request type [%d]", ptr->pid, item->req_type);
1139
1140         switch (ptr->pid) {
1141         case 0: /* child */
1142                 switch (item->req_type) {
1143                 case COMM_REQ_TO_INSTALLER:
1144                         DBG("before run _get_backend_cmd()");
1145                         /*Check for efl-tpk app*/
1146                         backend_cmd = _get_backend_cmd(item->pkg_type);
1147                         if (backend_cmd == NULL)
1148                                 break;
1149
1150                         if (strcmp(item->pkg_type, "tpk") == 0) {
1151                                 ret = __is_efl_tpk_app(item->pkgid);
1152                                 if (ret == 1) {
1153                                         if (backend_cmd)
1154                                                 free(backend_cmd);
1155                                         backend_cmd = _get_backend_cmd("efltpk");
1156                                 }
1157                         }
1158
1159                         DBG("Try to exec [%s][%s]", item->pkg_type, backend_cmd);
1160                         fprintf(stdout, "Try to exec [%s][%s]\n", item->pkg_type, backend_cmd);
1161
1162                         char **args_vector = __generate_argv(item->args);
1163                         args_vector[0] = backend_cmd;
1164
1165                         /* Execute backend !!! */
1166                         __exec_with_arg_vector(backend_cmd, args_vector, item->uid);
1167                         free(backend_cmd);
1168                         break;
1169                 case COMM_REQ_TO_ACTIVATOR:
1170                         DBG("activator start");
1171                         int val = 0;
1172                         if (item->args[0] == '1')       /* activate */
1173                                 val = 1;
1174                         else if (item->args[0] == '0')  /* deactivate */
1175                                 val = 0;
1176                         else {
1177                                 DBG("error in args parameter:[%c]\n",
1178                                     item->args[0]);
1179                                 exit(1);
1180                         }
1181
1182                         DBG("activated val %d", val);
1183
1184                         gboolean ret_parse;
1185                         gint argcp;
1186                         gchar **argvp;
1187                         GError *gerr = NULL;
1188                         char *label = NULL;
1189                         user_ctx* user_context = get_user_context(item->uid);
1190                         if(!user_context) {
1191                                 DBG("Failed to getenv for the user : %d", item->uid);
1192                                 exit(1);
1193                         }
1194                         if(set_environement(user_context)){
1195                                 DBG("Failed to set env for the user : %d", item->uid);
1196                                 exit(1);
1197                         }
1198                         free_user_context(user_context);
1199
1200                         ret_parse = g_shell_parse_argv(item->args,
1201                                                        &argcp, &argvp, &gerr);
1202                         if (FALSE == ret_parse) {
1203                                 DBG("Failed to split args: %s", item->args);
1204                                 DBG("messsage: %s", gerr->message);
1205                                 exit(1);
1206                         }
1207
1208                         if (!strcmp(argvp[1], "APP")) { /* in case of application */
1209                                 DBG("(De)activate APP");
1210                                 int opt;
1211                                 while ((opt = getopt(argcp, argvp, "l:")) != -1) {
1212                                         switch (opt) {
1213                                         case 'l':
1214                                                 label = strdup(optarg);
1215                                                 DBG("activated label %s", label);
1216                                                 break;
1217                                         default: /* '?' */
1218                                                 ERR("Incorrect argument %s\n", item->args);
1219                                                 exit(1);
1220                                         }
1221                                 }
1222
1223                                 ret = pkgmgrinfo_appinfo_set_usr_state_enabled(item->pkgid, val, item->uid);
1224                                 if (ret != PMINFO_R_OK) {
1225                                         perror("fail to activate/deactivte package");
1226                                         exit(1);
1227                                 }
1228
1229                                 if (label) {
1230                                         ret = pkgmgrinfo_appinfo_set_usr_default_label(item->pkgid, label, item->uid);
1231                                         if (ret != PMINFO_R_OK) {
1232                                                 perror("fail to activate/deactivte package");
1233                                                 exit(1);
1234                                         }
1235                                         free(label);
1236                                 }
1237                         } else { /* in case of package */
1238                                 ERR("(De)activate PKG[pkgid=%s, val=%d]", item->pkgid, val);
1239                                 char *manifest = NULL;
1240                                 manifest = pkgmgr_parser_get_manifest_file(item->pkgid);
1241                                 if (manifest == NULL) {
1242                                         ERR("Failed to fetch package manifest file\n");
1243                                         exit(1);
1244                                 }
1245                                 ERR("manifest : %s\n", manifest);
1246
1247                                 if (val) {
1248                                         pkgmgrinfo_pkginfo_h handle;
1249                                         ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(item->pkgid, item->uid, &handle);
1250                                         if (ret < 0) {
1251                                                 ret = pkgmgr_parser_parse_usr_manifest_for_installation(manifest,item->uid, NULL);
1252                                                 if (ret < 0) {
1253                                                         ERR("insert in db failed\n");
1254                                                 }
1255                                         } else {
1256                                                 pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
1257                                         }
1258
1259                                         ret = pkgmgrinfo_appinfo_set_usr_state_enabled(item->pkgid, val, item->uid);
1260                                         if (ret != PMINFO_R_OK) {
1261                                                 perror("fail to activate/deactivte package");
1262                                                 exit(1);
1263                                         }
1264                                 }
1265                                 else
1266                                         ret = pkgmgr_parser_parse_usr_manifest_for_uninstallation(manifest, item->uid, NULL);
1267
1268                                 if (ret < 0) {
1269                                         ERR("insert in db failed\n");
1270                                         exit(1);
1271                                 }
1272                         }
1273                         break;
1274                 case COMM_REQ_TO_MOVER:
1275                 case COMM_REQ_TO_CLEARER:
1276                         DBG("cleaner start");
1277                         DBG("before run _get_backend_cmd()");
1278                         backend_cmd = _get_backend_cmd(item->pkg_type);
1279                         if (NULL == backend_cmd)
1280                                 break;
1281
1282                         DBG("Try to exec [%s][%s]", item->pkg_type, backend_cmd);
1283                         fprintf(stdout, "Try to exec [%s][%s]\n", item->pkg_type, backend_cmd);
1284
1285                         char **args_vectors = __generate_argv(item->args);
1286                         args_vectors[0] = backend_cmd;
1287
1288                         /* Execute backend !!! */
1289                         __exec_with_arg_vector(backend_cmd, args_vectors, item->uid);
1290                         free(backend_cmd);
1291                         break;
1292                 case COMM_REQ_GET_SIZE:
1293                         DBG("before run _get_backend_cmd()");
1294                         __exec_with_arg_vector("usr/bin/pkg_getsize", __generate_argv(item->args), item->uid);
1295                         break;
1296                 case COMM_REQ_KILL_APP:
1297                 case COMM_REQ_CHECK_APP:
1298                         DBG("COMM_REQ_CHECK_APP start");
1299                         pkgmgrinfo_pkginfo_h handle;
1300                         ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(item->pkgid, item->uid, &handle);
1301                         if (ret < 0) {
1302                                 DBG("Failed to get handle\n");
1303                                 exit(1);
1304                         }
1305
1306                         if (item->req_type == COMM_REQ_KILL_APP) {
1307                                 ret = pkgmgrinfo_appinfo_get_usr_list(handle, PMSVC_ALL_APP, __pkgcmd_app_cb, "kill", item->uid);
1308                                 if (ret < 0) {
1309                                         DBG("pkgmgrinfo_appinfo_get_list() failed\n");
1310                                         pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
1311                                         exit(1);
1312                                 }
1313                         } else if (item->req_type == COMM_REQ_CHECK_APP) {
1314                                 ret = pkgmgrinfo_appinfo_get_usr_list(handle, PMSVC_ALL_APP, __pkgcmd_app_cb, "check", item->uid);
1315                                 if (ret < 0) {
1316                                         DBG("pkgmgrinfo_appinfo_get_list() failed\n");
1317                                         pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
1318                                         exit(1);
1319                                 }
1320                         }
1321                         pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
1322                         break;
1323                 }
1324                 /* exit child */
1325                 _save_queue_status(item, "done");
1326                 exit(0);
1327                 break;
1328
1329         case -1:
1330                 fprintf(stderr, "Fail to execute_fork()\n");
1331                 exit(1);
1332
1333         default:        /* parent */
1334                 DBG("parent exit\n");
1335                 _save_queue_status(item, "done");
1336                 break;
1337         }
1338
1339         free(item);
1340
1341         return FALSE;
1342 }
1343
1344 #define IS_WHITESPACE(CHAR) \
1345 ((CHAR == ' ' || CHAR == '\t' || CHAR == '\r' || CHAR == '\n') ? TRUE : FALSE)
1346
1347 void _app_str_trim(char *input)
1348 {
1349         char *trim_str = input;
1350
1351         if (input == NULL)
1352                 return;
1353
1354         while (*input != 0) {
1355                 if (!IS_WHITESPACE(*input)) {
1356                         *trim_str = *input;
1357                         trim_str++;
1358                 }
1359                 input++;
1360         }
1361
1362         *trim_str = 0;
1363         return;
1364 }
1365
1366 char *_get_backend_cmd(char *type)
1367 {
1368         FILE *fp = NULL;
1369         char buffer[1024] = { 0 };
1370         char *command = NULL;
1371         int size = 0;
1372         fp = fopen(PKG_CONF_PATH, "r");
1373         if (fp == NULL) {
1374                 return NULL;
1375         }
1376
1377         char *path = NULL;
1378         while (fgets(buffer, 1024, fp) != NULL) {
1379                 if (buffer[0] == '#')
1380                         continue;
1381
1382                 _app_str_trim(buffer);
1383
1384                 if ((path = strstr(buffer, PKG_BACKEND)) != NULL) {
1385                         DBG("buffer [%s]", buffer);
1386                         path = path + strlen(PKG_BACKEND);
1387                         DBG("path [%s]", path);
1388
1389                         command =
1390                             (char *)malloc(sizeof(char) * strlen(path) +
1391                                            strlen(type) + 1);
1392                         if (command == NULL) {
1393                                 fclose(fp);
1394                                 return NULL;
1395                         }
1396
1397                         size = strlen(path) + strlen(type) + 1;
1398                         snprintf(command, size, "%s%s", path, type);
1399                         command[strlen(path) + strlen(type)] = '\0';
1400                         DBG("command [%s]", command);
1401
1402                         if (fp != NULL)
1403                                 fclose(fp);
1404
1405                         return command;
1406                 }
1407
1408                 memset(buffer, 0x00, 1024);
1409         }
1410
1411         if (fp != NULL)
1412                 fclose(fp);
1413
1414         return NULL;            /* cannot find proper command */
1415 }
1416
1417 int main(int argc, char *argv[])
1418 {
1419         FILE *fp_status = NULL;
1420         char buf[32] = { 0, };
1421         pid_t pid;
1422         char *backend_cmd = NULL;
1423         char *backend_name = NULL;
1424         int r;
1425
1426         DBG("server start");
1427
1428         if (argv[1] && (strcmp(argv[1], "init") == 0)) {
1429                 /* if current status is "processing",
1430                    execute related backend with '-r' option */
1431                 if (!(fp_status = fopen(STATUS_FILE, "r")))
1432                         return 0;       /*if file is not exist, terminated. */
1433                 /* if processing <-- unintended termination */
1434                 if (fgets(buf, 32, fp_status) &&
1435                                 strcmp(buf, "processing") == 0) {
1436                         pid = fork();
1437                         if (pid == 0) { /* child */
1438                                 if (fgets(buf, 32, fp_status))
1439                                         backend_cmd = _get_backend_cmd(buf);
1440                                 if (!backend_cmd) {     /* if NULL, */
1441                                         DBG("fail to get"
1442                                                         " backend command");
1443                                         goto err;
1444                                 }
1445                                 backend_name =
1446                                         strrchr(backend_cmd, '/');
1447
1448                                 execl(backend_cmd, backend_name, "-r",
1449                                                 NULL);
1450                                 if (backend_cmd)
1451                                         free(backend_cmd);
1452                                 fprintf(fp_status, " ");
1453 err:
1454                                 fclose(fp_status);
1455                                 exit(13);
1456                         } else if (pid < 0) {   /* error */
1457                                 DBG("fork fail");
1458                                 fclose(fp_status);
1459                                 return 0;
1460                         } else {        /* parent */
1461
1462                                 DBG("parent end\n");
1463                                 fprintf(fp_status, " ");
1464                                 fclose(fp_status);
1465                                 return 0;
1466                         }
1467                 }
1468         }
1469
1470         r = _pm_queue_init();
1471         if (r) {
1472                 DBG("Queue Initialization Failed\n");
1473                 return -1;
1474         }
1475
1476         r = __init_backend_info();
1477         if (r) {
1478                 DBG("backend info init failed");
1479                 return -1;
1480         }
1481
1482         r = cynara_initialize(&p_cynara, NULL);
1483         if (r != CYNARA_API_SUCCESS) {
1484                 ERR("cynara initialize failed with code=%d", r);
1485                 return -1;
1486         }
1487
1488 #if !GLIB_CHECK_VERSION(2,35,0)
1489         g_type_init();
1490 #endif
1491         mainloop = g_main_loop_new(NULL, FALSE);
1492         if (!mainloop) {
1493                 ERR("g_main_loop_new failed");
1494                 return -1;
1495         }
1496
1497         DBG("Main loop is created.");
1498
1499         PkgMgrObject *pkg_mgr;
1500         pkg_mgr = g_object_new(PKG_MGR_TYPE_OBJECT, NULL);
1501         pkg_mgr_set_request_callback(pkg_mgr, req_cb, NULL);
1502         DBG("pkg_mgr object is created, and request callback is registered.");
1503
1504         g_main_loop_run(mainloop);
1505
1506         DBG("Quit main loop.");
1507         _pm_queue_final();
1508         __fini_backend_info();
1509         cynara_finish(p_cynara);
1510
1511         DBG("package manager server terminated.");
1512
1513         return 0;
1514 }