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.
23 /* System Include files */
28 #include <sys/types.h>
44 /* SLP include files */
45 #include "rpm-installer.h"
46 #include "rpm-installer-util.h"
49 #define QUERY_PACKAGE "/usr/bin/query_rpm_package.sh"
50 #define RPM_PKG_INFO "/var/rpmpkg.info"
52 struct pkgfile_info_t {
56 typedef struct pkgfile_info_t pkgfile_info;
58 extern char *gpkgname;
59 extern int do_upgrade;
60 static int __ri_xsystem_with_dup(char *pkgid, int fd);
61 static int __ri_recursive_delete_dir(char *dirname);
63 static int __ri_recursive_delete_dir(char *dirname)
67 char abs_filename[FILENAME_MAX];
68 struct stat stFileInfo;
69 dp = opendir(dirname);
71 while (ep = readdir(dp)) {
72 snprintf(abs_filename, FILENAME_MAX, "%s/%s", dirname,
74 if (lstat(abs_filename, &stFileInfo) < 0)
76 if (S_ISDIR(stFileInfo.st_mode)) {
77 if (strcmp(ep->d_name, ".") &&
78 strcmp(ep->d_name, "..")) {
79 __ri_recursive_delete_dir(abs_filename);
88 _d_msg(DEBUG_ERR, "Couldn't open the directory\n");
89 return RPM_INSTALLER_ERR_CLEAR_DATA_FAILED;
92 return RPM_INSTALLER_SUCCESS;
95 pkginfo *_rpm_installer_get_pkgfile_info(char *pkgfile)
104 rpmVSFlags vsflags = 0;
105 pkginfo *info = NULL;
108 info = malloc(sizeof(pkginfo));
110 _d_msg(DEBUG_ERR, "Malloc Failed\n");
117 fd = Fopen(pkgfile, "r.ufdio");
118 if ((!fd) || Ferror(fd)) {
119 _d_msg(DEBUG_ERR, "Failed to open package file (%s)\n", Fstrerror(fd));
128 vsflags |= _RPMVSF_NODIGESTS;
129 vsflags |= _RPMVSF_NOSIGNATURES;
130 vsflags |= RPMVSF_NOHDRCHK;
131 (void) rpmtsSetVSFlags(ts, vsflags);
133 rc = rpmReadPackageFile(ts, fd, pkgfile, &hdr);
134 if (rc != RPMRC_OK) {
135 _d_msg(DEBUG_ERR, "Could not read package file\n");
142 headerGet(hdr, RPMTAG_NAME, td, HEADERGET_MINMEM);
143 strncpy(info->package_name, rpmtdGetString(td), sizeof(info->package_name) - 1);
144 _d_msg(DEBUG_INFO, "Package Name : %s\n", info->package_name);
147 headerGet(hdr, RPMTAG_VERSION, td, HEADERGET_MINMEM);
148 strncpy(info->version, rpmtdGetString(td), sizeof(info->version) - 1);
149 _d_msg(DEBUG_INFO, "Version : %s\n", info->version);
162 pkginfo *_rpm_installer_get_pkgname_info(char *pkgid)
167 rpmdbMatchIterator mi;
170 pkginfo *info = NULL;
173 info = malloc(sizeof(pkginfo));
175 _d_msg(DEBUG_ERR, "Malloc Failed\n");
183 mi = rpmtsInitIterator(ts, RPMDBI_PACKAGES, NULL, 0);
184 while (NULL != (hdr = rpmdbNextIterator(mi))) {
186 hdr = headerLink(hdr);
187 rc = headerGet(hdr, RPMTAG_NAME, tn, HEADERGET_MINMEM);
188 if (strcmp(pkgid, rpmtdGetString(tn)) == 0) {
199 _d_msg(DEBUG_ERR, "Package not found in DB\n");
205 headerGet(hdr, RPMTAG_NAME, tn, HEADERGET_MINMEM);
206 strncpy(info->package_name, rpmtdGetString(tn),
207 sizeof(info->package_name)-1);
208 _d_msg(DEBUG_INFO, "Package Name : %s\n", info->package_name);
210 headerGet(hdr, RPMTAG_VERSION, tv, HEADERGET_MINMEM);
211 strncpy(info->version, rpmtdGetString(tv), sizeof(info->version)-1);
212 _d_msg(DEBUG_INFO, "Version : %s\n", info->version);
221 rpmdbFreeIterator(mi);
230 static int __ri_xsystem_with_dup(char *pkgname, int fd)
234 const char *argv[] = { QUERY_PACKAGE, pkgname, NULL };
238 perror("fork failed");
244 dup(fd); /* dup called twice to create copy of fd 1 and fd 2 */
245 execvp(argv[0], (char *const *)argv);
250 if (waitpid(pid, &status, 0) == -1) {
251 perror("waitpid failed");
254 if (WIFSIGNALED(status)) {
256 printf("sig no. %d\n", WTERMSIG(status));
259 if (!WIFEXITED(status)) {
260 perror("should not happen");
264 return WEXITSTATUS(status);
267 pkginfo *_rpm_installer_get_pkg_info(char *pkgname)
269 pkginfo *info = NULL;
276 char *saveptr = NULL;
282 fd = open(RPM_PKG_INFO, O_CREAT | O_RDWR, 0644);
284 _d_msg(DEBUG_ERR, "open failed\n");
288 err = __ri_xsystem_with_dup(pkgname, fd);
290 "[_rpm_installer_get_pkg_info] _xsystem returns %d\n", err);
293 "[_rpm_installer_get_pkg_info] "
294 "Package Not installed \n");
297 } else if (err == 2) {
299 "[_rpm_installer_get_pkg_info] "
300 "package already install\n");
301 info = malloc(sizeof(pkginfo));
303 _d_msg(DEBUG_ERR, "Malloc Failed\n");
307 memset(info, 0x00, sizeof(pkginfo));
309 fp = fopen(RPM_PKG_INFO, "r");
311 _d_msg(DEBUG_ERR, "fopen failed\n");
315 /* Now open file and get pkgname and version */
316 while ((read = getline(&line, &len, fp)) != -1) {
317 int len = strlen(line);
318 line[len - 1] = '\0';
320 _d_msg(DEBUG_INFO, "line[%s]\n", line);
322 tok = strtok_r(line, " ", &saveptr); /*Name */
323 if (tok && strncmp(tok, "Name", 4) == 0) {
325 tok = strtok_r(NULL, " ", &saveptr);
327 tok = strtok_r(NULL, " ", &saveptr);
329 strncpy(info->package_name, tok,
330 sizeof(info->package_name));
332 } else if (tok && strncmp(tok, "Version", 7) == 0) {
334 tok = strtok_r(NULL, " ", &saveptr);
336 tok = strtok_r(NULL, " ", &saveptr);
338 strncpy(info->version, tok,
339 sizeof(info->version));
350 remove(RPM_PKG_INFO);
355 "[_rpm_installer_get_pkg_info] "
356 "_xsystem returns error = %d\n", err);
360 remove(RPM_PKG_INFO);
367 int _rpm_installer_package_install(char *pkgfilepath, bool forceinstall,
368 char *installoptions)
371 if (forceinstall == true && installoptions == NULL)
372 return RPM_INSTALLER_ERR_WRONG_PARAM;
373 pkginfo *info = NULL;
374 pkginfo *tmpinfo = NULL;
375 /*Check to see if the package is already installed or not
376 If it is installed, compare the versions. If the current version
377 is higher than the installed version, upgrade it automatically
378 else ask for user confirmation before downgrading */
380 info = _rpm_installer_get_pkgfile_info(pkgfilepath);
382 /* failed to get pkg info */
383 return RPM_INSTALLER_ERR_UNKNOWN;
386 _ri_set_backend_state_info(GOT_PACKAGE_INFO_SUCCESSFULLY);
391 gpkgname = strdup(info->package_name);
393 tmpinfo = _rpm_installer_get_pkgname_info(info->package_name);
394 if (tmpinfo == NULL) {
395 /* package is not installed. Go for installation. */
400 err = _rpm_install_pkg(pkgfilepath, installoptions);
403 "install complete with error(%d)\n", err);
406 _ri_set_backend_state_info(REQUEST_COMPLETED);
407 return RPM_INSTALLER_SUCCESS;
409 } else if (strcmp(info->version, tmpinfo->version) > 0) {
411 err = _rpm_upgrade_pkg(pkgfilepath, "--force");
414 "upgrade complete with error(%d)\n", err);
425 _ri_set_backend_state_info(REQUEST_COMPLETED);
434 return RPM_INSTALLER_SUCCESS;
436 } else if (strcmp(info->version, tmpinfo->version) < 0) {
437 /*show popup and confirm from user */
438 switch (do_upgrade) {
440 _ri_set_backend_state_info(REQUEST_PENDING);
449 return RPM_INSTALLER_ERR_NEED_USER_CONFIRMATION;
460 _ri_set_backend_state_info(REQUEST_COMPLETED);
461 return RPM_INSTALLER_ERR_PACKAGE_NOT_UPGRADED;
463 /*continue with downgrade */
464 _ri_set_backend_state_info
465 (GOT_PACKAGE_INFO_SUCCESSFULLY);
466 err = _rpm_upgrade_pkg(pkgfilepath, "--force");
469 "upgrade complete with error(%d)\n",
481 _ri_set_backend_state_info(REQUEST_COMPLETED);
490 return RPM_INSTALLER_SUCCESS;
495 /*same package. Reinstall it. Manifest should be parsed again */
496 err = _rpm_upgrade_pkg(pkgfilepath, "--force");
499 "upgrade complete with error(%d)\n", err);
510 _ri_set_backend_state_info(REQUEST_COMPLETED);
519 return RPM_INSTALLER_SUCCESS;
530 return RPM_INSTALLER_SUCCESS;
534 int _rpm_installer_package_uninstall(char *pkgid)
537 pkginfo *tmppkginfo = _rpm_installer_get_pkgname_info(pkgid);
538 if (tmppkginfo == NULL)
539 return RPM_INSTALLER_ERR_PACKAGE_NOT_INSTALLED;
549 gpkgname = strdup(pkgid);
550 _ri_broadcast_status_notification(pkgid, "start", "uninstall");
551 _ri_broadcast_status_notification(pkgid, "command", "Uninstall");
553 _ri_set_backend_state_info(GOT_PACKAGE_INFO_SUCCESSFULLY);
554 ret = _rpm_uninstall_pkg(pkgid);
556 _ri_set_backend_state_info(REQUEST_COMPLETED);
561 int _rpm_installer_clear_private_data(char *pkgid)
564 return RPM_INSTALLER_ERR_WRONG_PARAM;
565 char dir_path[256] = { '\0' };
567 snprintf(dir_path, 255, "/opt/usr/apps/%s/data/", pkgid);
568 ret = __ri_recursive_delete_dir(dir_path);