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.
35 #include "rpm-installer.h"
36 #include "rpm-frontend.h"
37 #include <pkgmgr_installer.h>
39 #define RPM "/usr/etc/package-manager/backend/rpm"
41 char *gpkgname = NULL;
42 extern char scrolllabel[256];
50 struct ri_backend_data_t {
57 typedef struct ri_backend_data_t ri_backend_data;
58 static int __ri_native_recovery(int lastbackstate);
59 static int __ri_uninstall_package(char *pkgid);
60 static int __ri_clear_private_data(char *pkgid);
61 static int __ri_move_package(char *pkgid, int move_type);
62 static inline int __ri_read_proc(const char *path, char *buf, int size);
63 static inline int __ri_find_pid_by_cmdline(const char *dname,
66 static bool __ri_is_another_instance_running(const char *exepath);
68 static int __ri_uninstall_package(char *pkgid)
72 return RPM_INSTALLER_ERR_WRONG_PARAM;
74 ret = _rpm_installer_package_uninstall(pkgid);
75 if (ret == RPM_INSTALLER_ERR_PACKAGE_NOT_INSTALLED) {
76 _d_msg(DEBUG_ERR, "[__ri_uninstall_package]%s "
77 "not installed\n", pkgid);
78 } else if (ret != 0) {
80 "[__ri_uninstall_package]%s uninstall failed(%d)\n",
84 "[__ri_uninstall_package]%s successfully uninstalled\n",
90 static int __ri_clear_private_data(char *pkgid)
93 return RPM_INSTALLER_ERR_WRONG_PARAM;
95 ret = _rpm_installer_clear_private_data(pkgid);
96 if (ret == RPM_INSTALLER_SUCCESS) {
98 "[__clear_private_data]%s clear data successful\n",
102 "[__clear_private_data]%s clear data failed(%d)\n",
108 static int __ri_move_package(char *pkgid, int move_type)
111 return RPM_INSTALLER_ERR_WRONG_PARAM;
113 ret = _rpm_move_pkg(pkgid, move_type);
114 if (ret == RPM_INSTALLER_SUCCESS) {
116 "[__ri_move_package]%s move successful\n",
120 "[__ri_move_package]%s move failed(%d)\n",
126 static inline int __ri_read_proc(const char *path, char *buf, int size)
131 if (buf == NULL || path == NULL)
134 fd = open(path, O_RDONLY);
138 ret = read(fd, buf, size - 1);
150 static inline int __ri_find_pid_by_cmdline(const char *dname,
155 if (strncmp(cmdline, priv, strlen(RPM)) == 0) {
157 if (pid != getpgid(pid))
166 static bool __ri_is_another_instance_running(const char *exepath)
169 struct dirent *dentry;
172 char buf[256] = { 0, };
173 char buf1[256] = { 0, };
174 dp = opendir("/proc");
178 while ((dentry = readdir(dp)) != NULL) {
179 if (!isdigit(dentry->d_name[0]))
181 snprintf(buf, sizeof(buf), "/proc/%s/cmdline", dentry->d_name);
182 ret = __ri_read_proc(buf, buf1, sizeof(buf));
185 pid = __ri_find_pid_by_cmdline(dentry->d_name, buf1, exepath);
197 static int __ri_native_recovery(int lastbackstate)
203 char *installoptions = NULL;
205 _d_msg(DEBUG_INFO, "Rpm Installer Recovery Entry \n");
207 /* which package it was installing and what was state at that time */
208 _ri_get_last_input_info(&pn, &lreq, &opt);
210 switch (lastbackstate) {
211 case REQUEST_ACCEPTED:
212 case GOT_PACKAGE_INFO_SUCCESSFULLY:
214 * restart the last operation
217 "Rpm Installer Recovery started. state=%d \n", lastbackstate);
221 _rpm_installer_package_install(pn, true, "--force");
227 err = _rpm_installer_package_uninstall(pn);
237 "Recovery of command(%d) is to be implemented\n", lreq);
241 " Rpm Installer Recovery Ended \n");
243 case REQUEST_COMPLETED:
245 " Rpm Installer Recovery. Nothing To Be Done\n");
246 _ri_set_backend_state_info(REQUEST_COMPLETED);
249 case REQUEST_PENDING:
251 "Rpm Installer Recovery started. state=%d\n", lastbackstate);
252 /*Only package downgradation can be the case*/
253 err = _rpm_installer_package_install(pn, true, "--force");
254 if (err != RPM_INSTALLER_SUCCESS &&
255 err != RPM_INSTALLER_ERR_NEED_USER_CONFIRMATION) {
259 " Rpm Installer Recovery ended \n");
260 _ri_set_backend_state_info(REQUEST_COMPLETED);
269 " Rpm Installer Recovery Default state \n");
276 _d_msg(DEBUG_ERR, "Error in Recovery error number = (%d)\n",
282 int _rpm_backend_interface(char *keyid, char *pkgid, char *reqcommand)
285 ri_backend_data data = { 0 };
288 if (reqcommand == NULL) {
289 _d_msg(DEBUG_ERR, "reqcommand is NULL\n");
290 return RPM_INSTALLER_ERR_WRONG_PARAM;
292 if (keyid == NULL || pkgid == NULL) {
293 if (strncmp(reqcommand, "recover", strlen("recover"))) {
294 _d_msg(DEBUG_ERR, " Either keyid/pkgid is NULL\n");
295 return RPM_INSTALLER_ERR_WRONG_PARAM;
299 if (strncmp(reqcommand, "install", strlen("install")) == 0) {
300 data.req_cmd = INSTALL_CMD;
301 data.cmd_string = strdup("install");
302 if (data.cmd_string == NULL) {
304 "strdup failed due to insufficient memory\n");
306 } else if (strncmp(reqcommand, "remove", strlen("remove")) == 0) {
307 data.req_cmd = DELETE_CMD;
308 data.cmd_string = strdup("uninstall");
309 if (data.cmd_string == NULL) {
311 "strdup failed due to insufficient memory\n");
313 } else if (strncmp(reqcommand, "recover", strlen("recover")) == 0) {
314 data.req_cmd = RECOVER_CMD;
315 data.cmd_string = strdup("recover");
316 if (data.cmd_string == NULL) {
318 "strdup failed due to insufficient memory\n");
320 } else if (strncmp(reqcommand, "cleardata", strlen("cleardata")) == 0) {
321 data.req_cmd = CLEARDATA_CMD;
322 data.cmd_string = strdup("cleardata");
323 if (data.cmd_string == NULL) {
325 "strdup failed due to insufficient memory\n");
327 } else if (strncmp(reqcommand, "move", strlen("move")) == 0) {
328 data.req_cmd = MOVE_CMD;
329 data.cmd_string = strdup("move");
330 if (data.cmd_string == NULL) {
332 "strdup failed due to insufficient memory\n");
335 _d_msg(DEBUG_INFO, "wrong input parameter\n");
336 _d_msg(DEBUG_RESULT, "%d\n", RPM_INSTALLER_ERR_WRONG_PARAM);
337 return RPM_INSTALLER_ERR_WRONG_PARAM;
341 backendstate = _ri_get_backend_state();
343 rc = rpmReadConfigFiles(NULL, NULL);
344 if (rc == RPMRC_OK) {
345 _d_msg(DEBUG_INFO, "Successfully read rpm configuration\n");
347 _d_msg(DEBUG_ERR, "Unable to read RPM configuration.\n");
348 return RPM_INSTALLER_ERR_INTERNAL;
351 if (RECOVER_CMD == data.req_cmd) {
352 if (0 == backendstate) {
355 /* check the current state of backend */
356 lastbackstate = _ri_get_backend_state_info();
358 if (REQUEST_COMPLETED == lastbackstate) {
360 " Rpm Installer recovery is in REQUEST_COMPLETED \n");
361 snprintf(scrolllabel, sizeof(scrolllabel),
362 "No Recovery Needed");
364 ret = __ri_native_recovery(lastbackstate);
366 snprintf(scrolllabel, sizeof(scrolllabel),
369 snprintf(scrolllabel, sizeof(scrolllabel),
372 /* set the backend state as completed */
373 _ri_set_backend_state(1);
375 /* nothing to recover */
377 " Rpm Installer recovery Nothing to be done\n");
379 snprintf(scrolllabel, sizeof(scrolllabel),
380 "No Recovery Needed");
382 _d_msg(DEBUG_RESULT, "%d\n", ret);
386 if (backendstate == 0) {
390 * Another Instance may be running
391 * or something went wrong in last execution
394 if (__ri_is_another_instance_running(RPM)) {
396 _ri_broadcast_status_notification
397 (data.pkgid, "error",
398 "Another Instance Running");
399 _ri_stat_cb(data.pkgid, "error",
400 "Another Instance Running");
401 _ri_broadcast_status_notification
402 (data.pkgid, "end", "fail");
403 _ri_stat_cb(data.pkgid, "end",
406 _ri_broadcast_status_notification
408 "Another Instance Running");
409 _ri_stat_cb("unknown", "error",
410 "Another Instance Running");
411 _ri_broadcast_status_notification
412 ("unknown", "end", "fail");
413 _ri_stat_cb("unknown", "end", "fail");
417 "Another Instance is running \n");
418 ret = RPM_INSTALLER_ERR_RESOURCE_BUSY;
423 /* check the current state of backend */
424 lastbackstate = _ri_get_backend_state_info();
425 /* Publish Notification that backend has started */
426 _ri_broadcast_status_notification(data.pkgid,
429 _ri_broadcast_status_notification(data.pkgid,
432 if (REQUEST_COMPLETED == lastbackstate) {
434 " Rpm Installer recovery"
435 " is in REQUEST_COMPLETED \n");
438 ret = __ri_native_recovery(lastbackstate);
441 "recovery of last request failed\n");
444 "recovery of last request success\n");
447 /* set the backend state as completed */
448 _ri_set_backend_state(1);
452 /* set the backend state as started for the current request*/
453 _ri_set_backend_state(0);
456 gpkgname = strdup(data.pkgid);
458 /* Publish Notification that backend has started */
460 _ri_broadcast_status_notification(data.pkgid, "start",
463 _ri_broadcast_status_notification("unknown", "start",
467 _ri_set_backend_state_info(REQUEST_ACCEPTED);
469 /* Set the input request info */
470 _ri_save_last_input_info(data.pkgid, data.req_cmd,
471 data.force_overwrite);
473 switch (data.req_cmd) {
476 _d_msg(DEBUG_INFO, "[%s] --install %s\n",
477 "backend", data.pkgid);
479 _ri_broadcast_status_notification(data.pkgid,
480 "command", "Install");
482 if (data.force_overwrite == FORCE_OVERWITE) {
484 "[%s] --install %s --force-overwrite\n",
485 "backend", data.pkgid);
487 _rpm_installer_package_install
488 (data.pkgid, true, "--force");
490 _d_msg(DEBUG_INFO, "[%s] --install %s\n",
491 "backend", data.pkgid);
493 _rpm_installer_package_install
494 (data.pkgid, false, NULL);
496 if (ret == RPM_INSTALLER_ERR_NEED_USER_CONFIRMATION) {
498 } else if (ret == RPM_INSTALLER_SUCCESS) {
499 _d_msg(DEBUG_INFO, "install success\n");
500 _ri_broadcast_status_notification(data.pkgid,
502 _ri_stat_cb(data.pkgid, "end", "ok");
506 _ri_error_no_to_string(ret, &errstr);
507 _ri_broadcast_status_notification(data.pkgid,
510 _ri_stat_cb(data.pkgid, "error", errstr);
511 _ri_broadcast_status_notification(data.pkgid,
515 _ri_stat_cb(data.pkgid, "end", "fail");
517 "install failed with err(%d) (%s)\n",
524 _d_msg(DEBUG_INFO, "[%s] uninstall %s\n",
525 "backend", data.pkgid);
527 _ri_broadcast_status_notification(data.pkgid,
528 "command", "Remove");
530 ret = __ri_uninstall_package(data.pkgid);
533 _ri_error_no_to_string(ret, &errstr);
534 _ri_broadcast_status_notification(data.pkgid,
537 _ri_stat_cb(data.pkgid, "error", errstr);
539 _ri_broadcast_status_notification(data.pkgid,
542 _ri_stat_cb(data.pkgid, "end", "fail");
544 "remove failed with err(%d) (%s)\n",
547 _d_msg(DEBUG_INFO, "remove success\n");
548 _ri_broadcast_status_notification(data.pkgid,
550 _ri_stat_cb(data.pkgid, "end", "ok");
556 _d_msg(DEBUG_INFO, "[%s] clear data %s\n",
557 "backend", data.pkgid);
559 _ri_broadcast_status_notification(data.pkgid,
562 ret = __ri_clear_private_data(data.pkgid);
565 _ri_error_no_to_string(ret, &errstr);
566 _ri_broadcast_status_notification(data.pkgid,
569 _ri_stat_cb(data.pkgid, "error", errstr);
570 _ri_broadcast_status_notification(data.pkgid,
573 _ri_stat_cb(data.pkgid, "end", "fail");
575 "clear data failed with err(%d) (%s)\n",
578 _d_msg(DEBUG_INFO, "clear data success\n");
579 _ri_broadcast_status_notification(data.pkgid,
581 _ri_stat_cb(data.pkgid, "end", "ok");
587 _d_msg(DEBUG_INFO, "[%s] move %s\n",
588 "backend", data.pkgid);
590 _ri_broadcast_status_notification(data.pkgid,
593 ret = __ri_move_package(data.pkgid, move_type);
596 _ri_error_no_to_string(ret, &errstr);
597 _ri_broadcast_status_notification(data.pkgid,
600 _ri_stat_cb(data.pkgid, "error", errstr);
601 _ri_broadcast_status_notification(data.pkgid,
604 _ri_stat_cb(data.pkgid, "end", "fail");
606 "move failed with err(%d) (%s)\n",
609 _d_msg(DEBUG_INFO, "move success\n");
610 _ri_broadcast_status_notification(data.pkgid,
612 _ri_stat_cb(data.pkgid, "end", "ok");
618 _ri_broadcast_status_notification("unknown", "command",
620 _ri_broadcast_status_notification("unknown", "error",
622 _ri_stat_cb("unknown", "error", "not supported");
623 _ri_broadcast_status_notification("unknown",
625 _ri_stat_cb("unknown", "end", "fail");
626 _d_msg(DEBUG_ERR, "unknown command \n");
627 ret = RPM_INSTALLER_ERR_WRONG_PARAM;
636 if (data.cmd_string) {
637 free(data.cmd_string);
638 data.cmd_string = NULL;
641 if (_ri_get_backend_state_info() != REQUEST_PENDING) {
642 _ri_set_backend_state_info(REQUEST_COMPLETED);
643 /* set the backend state as completed */
644 _ri_set_backend_state(1);
645 _d_msg(DEBUG_RESULT, "%d\n", ret);