4 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
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>
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
13 * http://www.apache.org/licenses/LICENSE-2.0
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.
29 #include <sys/types.h>
33 #include <sys/types.h>
40 #include <pkgmgr-info.h>
41 #include <pkgmgr/pkgmgr_parser.h>
42 #include <tzplatform_config.h>
43 #include <drm-tizen-apps.h>
45 #include "pkgmgr_installer.h"
46 #include "pkgmgr-server.h"
48 #include "comm_config.h"
49 #include "package-manager.h"
52 #define NO_MATCHING_FILE 11
55 #define GLOBAL_USER tzplatform_getuid(TZ_SYS_GLOBALAPP_USER)
65 8 bit value to represent maximum 8 backends.
66 Each bit position corresponds to a queue slot which
67 is dynamically determined.
69 char backend_busy = 0;
70 extern int num_of_backends;
72 struct signal_info_t {
77 static int pipe_sig[2];
78 static GIOChannel *pipe_io;
79 static guint pipe_wid;
82 extern queue_info_map *start;
85 GMainLoop *mainloop = NULL;
90 OPERATION_INSTALL = 0,
97 static int __check_backend_status_for_exit(void);
98 static int __check_queue_status_for_exit(void);
99 static int __is_backend_busy(int position);
100 static void __set_backend_busy(int position);
101 static void __set_backend_free(int position);
102 static void sighandler(int signo);
104 gboolean exit_server(void *data);
106 /* To check whether a particular backend is free/busy*/
107 static int __is_backend_busy(int position)
109 return backend_busy & 1<<position;
111 /*To set a particular backend as busy*/
112 static void __set_backend_busy(int position)
114 backend_busy = backend_busy | 1<<position;
116 /*To set a particular backend as free */
117 static void __set_backend_free(int position)
119 backend_busy = backend_busy & ~(1<<position);
122 static int __is_global(uid_t uid)
124 return (uid == OWNER_ROOT || uid == GLOBAL_USER) ? 1 : 0;
127 static const char *__get_recovery_file_path(uid_t uid)
131 if (!__is_global(uid))
132 tzplatform_set_user(uid);
134 path = tzplatform_getenv(__is_global(uid)
135 ? TZ_SYS_RW_PACKAGES : TZ_USER_PACKAGES);
137 tzplatform_reset_user();
142 static void __set_recovery_mode(uid_t uid, char *pkgid, char *pkg_type)
144 char recovery_file[MAX_PKG_NAME_LEN] = { 0, };
145 char buffer[MAX_PKG_NAME_LEN] = { 0 };
146 char *pkgid_tmp = NULL;
147 FILE *rev_file = NULL;
150 DBG("pkgid is null\n");
154 /*if pkgid has a "/"charactor, that is a path name for installation, then extract pkgid from absolute path*/
155 if (strstr(pkgid, "/")) {
156 pkgid_tmp = strrchr(pkgid, '/') + 1;
157 if (pkgid_tmp == NULL) {
158 DBG("pkgid_tmp[%s] is null\n", pkgid);
161 snprintf(recovery_file, sizeof(recovery_file), "%s/%s", __get_recovery_file_path(uid), pkgid_tmp);
163 snprintf(recovery_file, sizeof(recovery_file), "%s/%s", __get_recovery_file_path(uid), pkgid);
166 rev_file = fopen(recovery_file, "w");
167 if (rev_file== NULL) {
168 DBG("rev_file[%s] is null\n", recovery_file);
172 snprintf(buffer, MAX_PKG_NAME_LEN, "pkgid : %s\n", pkgid);
173 fwrite(buffer, sizeof(char), strlen(buffer), rev_file);
178 static void __unset_recovery_mode(uid_t uid, char *pkgid, char *pkg_type)
181 char recovery_file[MAX_PKG_NAME_LEN] = { 0, };
182 char *pkgid_tmp = NULL;
185 DBG("pkgid is null\n");
189 /*if pkgid has a "/"charactor, that is a path name for installation, then extract pkgid from absolute path*/
190 if (strstr(pkgid, "/")) {
191 pkgid_tmp = strrchr(pkgid, '/') + 1;
192 if (pkgid_tmp == NULL) {
193 DBG("pkgid_tmp[%s] is null\n", pkgid);
196 snprintf(recovery_file, sizeof(recovery_file), "%s/%s", __get_recovery_file_path(uid), pkgid_tmp);
198 snprintf(recovery_file, sizeof(recovery_file), "%s/%s", __get_recovery_file_path(uid), pkgid);
201 ret = remove(recovery_file);
203 DBG("remove recovery_file[%s] fail\n", recovery_file);
206 static void send_fail_signal(char *pname, char *ptype, char *args)
208 DBG("send_fail_signal start\n");
213 pkgmgr_installer *pi;
214 pi = pkgmgr_installer_new();
216 DBG("Failure in creating the pkgmgr_installer object");
219 ret_parse = g_shell_parse_argv(args,
220 &argcp, &argvp, &gerr);
221 if (FALSE == ret_parse) {
222 DBG("Failed to split args: %s", args);
223 DBG("messsage: %s", gerr->message);
224 pkgmgr_installer_free(pi);
228 pkgmgr_installer_receive_request(pi, argcp, argvp);
229 pkgmgr_installer_send_signal(pi, ptype, pname, "end", "fail");
230 pkgmgr_installer_free(pi);
234 static gboolean pipe_io_handler(GIOChannel *io, GIOCondition cond, gpointer data)
240 struct signal_info_t info;
241 backend_info *ptr = begin;
243 s = g_io_channel_read_chars(io, (gchar *)&info, sizeof(struct signal_info_t), &len, &err);
244 if (s != G_IO_STATUS_NORMAL) {
245 ERR("Signal pipe read failed: %s", err->message);
250 for (x = 0; x < num_of_backends; x++, ptr++) {
251 if (ptr && ptr->pid == info.pid)
255 if (x == num_of_backends) {
256 ERR("Unknown child exit");
260 __set_backend_free(x);
261 __unset_recovery_mode(ptr->uid, ptr->pkgid, ptr->pkgtype);
262 if (WIFSIGNALED(info.status) || WEXITSTATUS(info.status)) {
263 send_fail_signal(ptr->pkgid, ptr->pkgtype, ptr->args);
264 DBG("backend[%s] exit with error", ptr->pkgtype);
266 DBG("backend[%s] exit", ptr->pkgtype);
269 g_idle_add(queue_job, NULL);
274 static int __init_backend_info(void)
278 /*Allocate memory for holding pid, pkgtype and pkgid*/
279 ptr = (backend_info*)calloc(num_of_backends, sizeof(backend_info));
281 DBG("Malloc Failed\n");
286 if (pipe(pipe_sig)) {
287 ERR("create pipe failed");
291 pipe_io = g_io_channel_unix_new(pipe_sig[0]);
292 g_io_channel_set_encoding(pipe_io, NULL, NULL);
293 g_io_channel_set_buffered(pipe_io, FALSE);
294 pipe_wid = g_io_add_watch(pipe_io, G_IO_IN, pipe_io_handler, NULL);
299 static void __fini_backend_info(void)
301 g_source_remove(pipe_wid);
302 g_io_channel_unref(pipe_io);
306 /*Free backend info */
310 static void sighandler(int signo)
312 struct signal_info_t info;
314 info.pid = waitpid(-1, &info.status, WNOHANG);
315 if (write(pipe_sig[1], &info, sizeof(struct signal_info_t)) < 0)
316 ERR("failed to write result: %s", strerror(errno));
319 static int __register_signal_handler(void)
321 static int sig_reg = 0;
322 struct sigaction act;
327 act.sa_handler = sighandler;
328 sigemptyset(&act.sa_mask);
329 act.sa_flags = SA_NOCLDSTOP;
330 if (sigaction(SIGCHLD, &act, NULL) < 0) {
331 ERR("signal: SIGCHLD failed\n");
335 g_timeout_add_seconds(2, exit_server, NULL);
341 static int __check_backend_status_for_exit(void)
344 for(i = 0; i < num_of_backends; i++)
346 if (!__is_backend_busy(i))
354 static int __check_queue_status_for_exit(void)
356 pm_queue_data *head[MAX_QUEUE_NUM] = {NULL,};
357 queue_info_map *ptr = NULL;
362 for(i = 0; i < entries; i++)
364 if (ptr->queue_slot <= slot) {
370 slot = ptr->queue_slot;
375 for(i = 0; i < num_of_backends; i++)
385 gboolean exit_server(void *data)
387 DBG("exit_server Start\n");
388 if (__check_backend_status_for_exit() &&
389 __check_queue_status_for_exit()) {
390 if (!getenv("PMS_STANDALONE")) {
391 g_main_loop_quit(mainloop);
398 static int __pkgcmd_read_proc(const char *path, char *buf, int size)
402 if (buf == NULL || path == NULL)
404 fd = open(path, O_RDONLY);
407 ret = read(fd, buf, size - 1);
417 static int __pkgcmd_find_pid_by_cmdline(const char *dname,
418 const char *cmdline, const char *apppath)
422 if (strcmp(cmdline, apppath) == 0) {
424 if (pid != getpgid(pid))
430 static int __pkgcmd_proc_iter_kill_cmdline(const char *apppath, int option)
433 struct dirent *dentry;
436 char buf[1024] = {'\0'};
439 dp = opendir("/proc");
444 while ((dentry = readdir(dp)) != NULL) {
445 if (!isdigit(dentry->d_name[0]))
448 snprintf(buf, sizeof(buf), "/proc/%s/cmdline", dentry->d_name);
449 ret = __pkgcmd_read_proc(buf, buf, sizeof(buf));
453 pid = __pkgcmd_find_pid_by_cmdline(dentry->d_name, buf, apppath);
464 if (killpg(pgid, SIGKILL) < 0) {
476 static void __make_pid_info_file(char *req_key, int pid)
480 char buf[MAX_PKG_TYPE_LEN] = {0};
481 char info_file[PATH_MAX] = {'\0'};
486 snprintf(info_file, PATH_MAX, "/tmp/pkgmgr/%s", req_key);
488 DBG("info_path(%s)", info_file);
489 file = fopen(info_file, "w");
491 ERR("Couldn't open the file(%s)", info_file);
495 snprintf(buf, MAX_PKG_TYPE_LEN, "%d\n", pid);
496 fwrite(buf, 1, strlen(buf), file);
504 static int __pkgcmd_app_cb(const pkgmgrinfo_appinfo_h handle, void *user_data)
511 if (handle == NULL) {
512 perror("appinfo handle is NULL\n");
515 ret = pkgmgrinfo_appinfo_get_exec(handle, &exec);
517 perror("Failed to get app exec path\n");
520 ret = pkgmgrinfo_appinfo_get_pkgid(handle, &pkgid);
522 perror("Failed to get pkgid\n");
526 if (strcmp(user_data, "kill") == 0)
527 pid = __pkgcmd_proc_iter_kill_cmdline(exec, 1);
528 else if(strcmp(user_data, "check") == 0)
529 pid = __pkgcmd_proc_iter_kill_cmdline(exec, 0);
531 __make_pid_info_file(pkgid, pid);
536 void free_user_context(user_ctx* ctx)
543 //env variable ends by NULL element
553 int set_environement(user_ctx *ctx)
560 if (setgid(ctx->gid)) {
561 ERR("setgid failed: %d", errno);
564 if (setuid(ctx->uid)) {
565 ERR("setuid failed: %d", errno);
569 //env variable ends by NULL element
571 if (putenv(env[i]) != 0)
578 user_ctx* get_user_context(uid_t uid)
580 /* we can use getpwnam because this is used only after a
581 * fork and just before an execv
582 * No concurrencial call can corrupt the data
583 * returned by getpwuid
585 user_ctx *context_res;
596 context_res = (user_ctx *)malloc(sizeof(user_ctx));
601 env = (char**)malloc(3* sizeof(char *));
606 // Build environment context
607 len = snprintf(NULL,0, "HOME=%s", pwd->pw_dir);
608 env[0] = (char*)malloc((len + 1)* sizeof(char));
613 sprintf(env[0], "HOME=%s", pwd->pw_dir);
614 len = snprintf(NULL,0, "USER=%s", pwd->pw_name);
615 env[1] = (char*)malloc((len + 1)* sizeof(char));
621 sprintf(env[1], "USER=%s", pwd->pw_name);
629 //env variable ends by NULL element
630 while (env && env[i]) {
637 context_res->env = env;
638 context_res->uid = uid;
639 context_res->gid = pwd->pw_gid;
644 static char **__generate_argv(const char *args)
646 /* Create args vector
647 * req_id + pkgid + args
649 * vector size = # of args +
650 *(req_id + pkgid + NULL termination = 3)
651 * Last value must be NULL for execv.
659 ret_parse = g_shell_parse_argv(args,
660 &argcp, &argvp, &gerr);
661 if (FALSE == ret_parse) {
662 DBG("Failed to split args: %s", args);
663 DBG("messsage: %s", gerr->message);
668 for (i = 0; i < argcp; i++)
669 DBG(">>>>>> argsv[%d]=%s", i, argvp[i]);
674 void __set_environment(gpointer user_data)
676 user_ctx *ctx = (user_ctx *)user_data;
678 if (set_environement(ctx))
679 DBG("Failed to set env for the user : %d", ctx->uid);
682 static int __exec_with_arg_vector(const char *cmd, char **argv, uid_t uid)
684 user_ctx* user_context;
685 GError *error = NULL;
689 user_context = get_user_context(uid);
691 DBG("Failed to getenv for the user : %d", uid);
695 ret = g_spawn_async(NULL, argv, NULL, G_SPAWN_DO_NOT_REAP_CHILD,
696 __set_environment, (gpointer)user_context, &pid,
699 ERR("Failed to excute backend: %s", error->message);
703 free_user_context(user_context);
708 static int __process_install(pm_dbus_msg *item)
712 char args[MAX_PKG_ARGS_LEN] = {'\0', };
715 backend_cmd = _get_backend_cmd(item->pkg_type);
716 if (backend_cmd == NULL)
719 snprintf(args, sizeof(args), "%s -k %s -i %s %s", backend_cmd,
720 item->req_id, item->pkgid, item->args);
722 argv = __generate_argv(args);
724 pid = __exec_with_arg_vector(backend_cmd, argv, item->uid);
731 static int __process_reinstall(pm_dbus_msg *item)
735 char args[MAX_PKG_ARGS_LEN];
738 backend_cmd = _get_backend_cmd(item->pkg_type);
739 if (backend_cmd == NULL)
742 snprintf(args, sizeof(args), "%s -k %s -r %s", backend_cmd,
743 item->req_id, item->pkgid);
744 argv = __generate_argv(args);
746 pid = __exec_with_arg_vector(backend_cmd, argv, item->uid);
754 static int __process_uninstall(pm_dbus_msg *item)
758 char args[MAX_PKG_ARGS_LEN];
761 backend_cmd = _get_backend_cmd(item->pkg_type);
762 if (backend_cmd == NULL)
765 snprintf(args, sizeof(args), "%s -k %s -d %s", backend_cmd,
766 item->req_id, item->pkgid);
767 argv = __generate_argv(args);
769 pid = __exec_with_arg_vector(backend_cmd, argv, item->uid);
777 static int __process_move(pm_dbus_msg *item)
781 char args[MAX_PKG_ARGS_LEN];
784 backend_cmd = _get_backend_cmd(item->pkg_type);
785 if (backend_cmd == NULL)
788 /* TODO: set movetype */
789 snprintf(args, sizeof(args), "%s -k %s -m %s -t %s", backend_cmd,
790 item->req_id, item->pkgid, item->args);
791 argv = __generate_argv(args);
793 pid = __exec_with_arg_vector(backend_cmd, argv, item->uid);
801 static int __process_enable(pm_dbus_msg *item)
807 static int __process_disable(pm_dbus_msg *item)
813 static int __process_enable_global_app(pm_dbus_msg *item)
815 pkgmgr_parser_update_global_app_disable_info_in_db(item->pkgid, item->uid, 0);
819 static int __process_disable_global_app(pm_dbus_msg *item)
821 pkgmgr_parser_update_global_app_disable_info_in_db(item->pkgid, item->uid, 1);
825 static int __process_getsize(pm_dbus_msg *item)
828 char args[MAX_PKG_ARGS_LEN];
831 snprintf(args, sizeof(args), "%s %s -k %s", item->pkgid, item->args,
833 argv = __generate_argv(args);
834 pid = __exec_with_arg_vector("/usr/bin/pkg_getsize", argv, item->uid);
841 static int __process_cleardata(pm_dbus_msg *item)
845 char args[MAX_PKG_ARGS_LEN];
848 backend_cmd = _get_backend_cmd(item->pkg_type);
849 if (backend_cmd == NULL)
852 /* TODO: set movetype */
853 snprintf(args, sizeof(args), "%s -k %s -c %s", backend_cmd,
854 item->req_id, item->pkgid);
855 argv = __generate_argv(args);
857 pid = __exec_with_arg_vector(backend_cmd, argv, item->uid);
865 static int __process_clearcache(pm_dbus_msg *item)
868 char args[MAX_PKG_ARGS_LEN];
871 snprintf(args, sizeof(args), "%s", item->pkgid);
872 argv = __generate_argv(args);
873 pid = __exec_with_arg_vector("/usr/bin/pkg_clearcache", argv, item->uid);
880 static int __process_kill(pm_dbus_msg *item)
883 pkgmgrinfo_pkginfo_h handle;
885 ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(item->pkgid, item->uid,
888 ERR("Failed to get handle");
892 ret = pkgmgrinfo_appinfo_get_usr_list(handle, PMINFO_ALL_APP,
893 __pkgcmd_app_cb, "kill", item->uid);
894 pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
896 ERR("pkgmgrinfo_appinfo_get_list() failed");
903 static int __process_check(pm_dbus_msg *item)
906 pkgmgrinfo_pkginfo_h handle;
908 ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(item->pkgid, item->uid,
911 ERR("Failed to get handle");
915 ret = pkgmgrinfo_appinfo_get_usr_list(handle, PMINFO_ALL_APP,
916 __pkgcmd_app_cb, "check", item->uid);
917 pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
919 ERR("pkgmgrinfo_appinfo_get_list() failed");
926 static int __process_generate_license_request(pm_dbus_msg *item)
930 char req_data[MAX_PKG_ARGS_LEN];
931 unsigned int req_data_len;
932 char license_url[MAX_PKG_ARGS_LEN];
933 unsigned int license_url_len;
935 resp_data = item->args;
936 req_data_len = sizeof(req_data);
937 license_url_len = sizeof(license_url);
939 ret = drm_tizen_generate_license_request(resp_data, strlen(resp_data),
940 req_data, &req_data_len, license_url, &license_url_len);
941 if (ret != TADC_SUCCESS) {
942 ERR("drm_tizen_generate_license_request failed: %d", ret);
943 __return_value_to_caller(item->req_id, g_variant_new("(iss)",
944 PKGMGR_R_ESYSTEM, "", ""));
948 __return_value_to_caller(item->req_id,
949 g_variant_new("(iss)", PKGMGR_R_OK, req_data,
955 static int __process_register_license(pm_dbus_msg *item)
960 resp_data = item->args;
962 ret = drm_tizen_register_license(resp_data, strlen(resp_data));
963 if (ret != TADC_SUCCESS) {
964 ERR("drm_tizen_register_license failed: %d", ret);
965 __return_value_to_caller(item->req_id,
966 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
970 __return_value_to_caller(item->req_id,
971 g_variant_new("(i)", PKGMGR_R_OK));
976 static int __process_decrypt_package(pm_dbus_msg *item)
980 char *decrypted_file_path;
982 drm_file_path = item->pkgid;
983 decrypted_file_path = item->args;
985 /* TODO: check ownership of decrypted file */
986 ret = drm_tizen_decrypt_package(drm_file_path, strlen(drm_file_path),
987 decrypted_file_path, strlen(decrypted_file_path));
988 if (ret != TADC_SUCCESS) {
989 ERR("drm_tizen_register_license failed: %d", ret);
990 __return_value_to_caller(item->req_id,
991 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
995 __return_value_to_caller(item->req_id,
996 g_variant_new("(i)", PKGMGR_R_OK));
1001 gboolean queue_job(void *data)
1003 pm_dbus_msg *item = NULL;
1008 /* Pop a job from queue */
1009 for (x = 0, ptr = begin; x < num_of_backends; x++, ptr++) {
1010 if (__is_backend_busy(x))
1013 item = _pm_queue_pop(x);
1014 if (item && item->req_type != -1)
1019 /* all backend messages queue are empty or busy */
1020 if (x == num_of_backends)
1023 __set_backend_busy(x);
1024 __set_recovery_mode(item->uid, item->pkgid, item->pkg_type);
1026 /*save pkg type and pkg name for future*/
1027 strncpy(ptr->pkgtype, item->pkg_type, MAX_PKG_TYPE_LEN-1);
1028 strncpy(ptr->pkgid, item->pkgid, MAX_PKG_NAME_LEN-1);
1029 strncpy(ptr->args, item->args, MAX_PKG_ARGS_LEN-1);
1030 ptr->uid = item->uid;
1031 DBG("handle request type [%d]", ptr->pid, item->req_type);
1033 switch (item->req_type) {
1034 case PKGMGR_REQUEST_TYPE_INSTALL:
1035 ret = __process_install(item);
1037 case PKGMGR_REQUEST_TYPE_REINSTALL:
1038 ret = __process_reinstall(item);
1040 case PKGMGR_REQUEST_TYPE_UNINSTALL:
1041 ret = __process_uninstall(item);
1043 case PKGMGR_REQUEST_TYPE_MOVE:
1044 ret = __process_move(item);
1046 case PKGMGR_REQUEST_TYPE_ENABLE:
1047 ret = __process_enable(item);
1049 case PKGMGR_REQUEST_TYPE_DISABLE:
1050 ret = __process_disable(item);
1052 case PKGMGR_REQUEST_TYPE_GETSIZE:
1053 ret = __process_getsize(item);
1055 case PKGMGR_REQUEST_TYPE_CLEARDATA:
1056 ret = __process_cleardata(item);
1058 case PKGMGR_REQUEST_TYPE_CLEARCACHE:
1059 ret = __process_clearcache(item);
1061 case PKGMGR_REQUEST_TYPE_ENABLE_GLOBAL_APP:
1062 ret = __process_enable_global_app(item);
1064 case PKGMGR_REQUEST_TYPE_DISABLE_GLOBAL_APP:
1065 ret = __process_disable_global_app(item);
1067 case PKGMGR_REQUEST_TYPE_KILL:
1068 ret = __process_kill(item);
1070 case PKGMGR_REQUEST_TYPE_CHECK:
1071 ret = __process_check(item);
1073 case PKGMGR_REQUEST_TYPE_GENERATE_LICENSE_REQUEST:
1074 ret = __process_generate_license_request(item);
1076 case PKGMGR_REQUEST_TYPE_REGISTER_LICENSE:
1077 ret = __process_register_license(item);
1079 case PKGMGR_REQUEST_TYPE_DECRYPT_PACKAGE:
1080 ret = __process_decrypt_package(item);
1093 #define IS_WHITESPACE(CHAR) \
1094 ((CHAR == ' ' || CHAR == '\t' || CHAR == '\r' || CHAR == '\n') ? TRUE : FALSE)
1096 void _app_str_trim(char *input)
1098 char *trim_str = input;
1103 while (*input != 0) {
1104 if (!IS_WHITESPACE(*input)) {
1115 char *_get_backend_cmd(char *type)
1118 char buffer[1024] = { 0 };
1119 char *command = NULL;
1121 fp = fopen(PKG_CONF_PATH, "r");
1127 while (fgets(buffer, 1024, fp) != NULL) {
1128 if (buffer[0] == '#')
1131 _app_str_trim(buffer);
1133 if ((path = strstr(buffer, PKG_BACKEND)) != NULL) {
1134 DBG("buffer [%s]", buffer);
1135 path = path + strlen(PKG_BACKEND);
1136 DBG("path [%s]", path);
1139 (char *)malloc(sizeof(char) * strlen(path) +
1141 if (command == NULL) {
1146 size = strlen(path) + strlen(type) + 1;
1147 snprintf(command, size, "%s%s", path, type);
1148 command[strlen(path) + strlen(type)] = '\0';
1149 DBG("command [%s]", command);
1157 memset(buffer, 0x00, 1024);
1163 return NULL; /* cannot find proper command */
1166 int main(int argc, char *argv[])
1168 FILE *fp_status = NULL;
1169 char buf[32] = { 0, };
1171 char *backend_cmd = NULL;
1172 char *backend_name = NULL;
1175 DBG("server start");
1177 if (argv[1] && (strcmp(argv[1], "init") == 0)) {
1178 /* if current status is "processing",
1179 execute related backend with '-r' option */
1180 if (!(fp_status = fopen(STATUS_FILE, "r")))
1181 return 0; /*if file is not exist, terminated. */
1182 /* if processing <-- unintended termination */
1183 if (fgets(buf, 32, fp_status) &&
1184 strcmp(buf, "processing") == 0) {
1186 if (pid == 0) { /* child */
1187 if (fgets(buf, 32, fp_status))
1188 backend_cmd = _get_backend_cmd(buf);
1189 if (!backend_cmd) { /* if NULL, */
1190 DBG("fail to get backend command");
1194 strrchr(backend_cmd, '/');
1195 if (!backend_name) {
1196 DBG("fail to get backend name");
1200 execl(backend_cmd, backend_name, "-r",
1204 fprintf(fp_status, " ");
1208 } else if (pid < 0) { /* error */
1212 } else { /* parent */
1214 DBG("parent end\n");
1215 fprintf(fp_status, " ");
1222 r = _pm_queue_init();
1224 DBG("Queue Initialization Failed\n");
1228 r = __init_backend_info();
1230 DBG("backend info init failed");
1234 r = __init_request_handler();
1236 ERR("dbus init failed");
1240 if (__register_signal_handler()) {
1241 ERR("failed to register signal handler");
1245 #if !GLIB_CHECK_VERSION(2,35,0)
1248 mainloop = g_main_loop_new(NULL, FALSE);
1250 ERR("g_main_loop_new failed");
1254 DBG("Main loop is created.");
1256 g_main_loop_run(mainloop);
1258 DBG("Quit main loop.");
1259 __fini_request_handler();
1260 __fini_backend_info();
1263 DBG("package manager server terminated.");