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 *pkgname, 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");
114 fd = Fopen(pkgfile, "r.ufdio");
115 if ((!fd) || Ferror(fd)) {
116 _d_msg(DEBUG_ERR, "Failed to open package file (%s)\n", Fstrerror(fd));
129 vsflags |= _RPMVSF_NODIGESTS;
130 vsflags |= _RPMVSF_NOSIGNATURES;
131 vsflags |= RPMVSF_NOHDRCHK;
132 (void) rpmtsSetVSFlags(ts, vsflags);
134 rc = rpmReadPackageFile(ts, fd, pkgfile, &hdr);
135 if (rc != RPMRC_OK) {
136 _d_msg(DEBUG_ERR, "Could not read package file\n");
143 headerGet(hdr, RPMTAG_NAME, td, HEADERGET_MINMEM);
144 strncpy(info->package_name, rpmtdGetString(td), sizeof(info->package_name));
145 _d_msg(DEBUG_INFO, "Package Name : %s\n", info->package_name);
148 headerGet(hdr, RPMTAG_VERSION, td, HEADERGET_MINMEM);
149 strncpy(info->version, rpmtdGetString(td), sizeof(info->version));
150 _d_msg(DEBUG_INFO, "Version : %s\n", info->version);
163 pkginfo *_rpm_installer_get_pkgname_info(char *pkgname)
168 rpmdbMatchIterator mi;
171 pkginfo *info = NULL;
174 info = malloc(sizeof(pkginfo));
176 _d_msg(DEBUG_ERR, "Malloc Failed\n");
185 mi = rpmtsInitIterator(ts, RPMDBI_PACKAGES, NULL, 0);
186 while (NULL != (hdr = rpmdbNextIterator(mi))) {
188 hdr = headerLink(hdr);
189 rc = headerGet(hdr, RPMTAG_NAME, tn, HEADERGET_MINMEM);
190 if (strcmp(pkgname, rpmtdGetString(tn)) == 0) {
195 hdr = headerFree(hdr);
201 _d_msg(DEBUG_ERR, "Package not found in DB\n");
207 headerGet(hdr, RPMTAG_NAME, tn, HEADERGET_MINMEM);
208 strncpy(info->package_name, rpmtdGetString(tn),
209 sizeof(info->package_name)-1);
210 _d_msg(DEBUG_INFO, "Package Name : %s\n", info->package_name);
212 headerGet(hdr, RPMTAG_VERSION, tv, HEADERGET_MINMEM);
213 strncpy(info->version, rpmtdGetString(tv), sizeof(info->version)-1);
214 _d_msg(DEBUG_INFO, "Version : %s\n", info->version);
223 rpmdbFreeIterator(mi);
232 static int __ri_xsystem_with_dup(char *pkgname, int fd)
236 const char *argv[] = { QUERY_PACKAGE, pkgname, NULL };
240 perror("fork failed");
246 dup(fd); /* dup called twice to create copy of fd 1 and fd 2 */
247 execvp(argv[0], (char *const *)argv);
252 if (waitpid(pid, &status, 0) == -1) {
253 perror("waitpid failed");
256 if (WIFSIGNALED(status)) {
258 printf("sig no. %d\n", WTERMSIG(status));
261 if (!WIFEXITED(status)) {
262 perror("should not happen");
266 return WEXITSTATUS(status);
269 pkginfo *_rpm_installer_get_pkg_info(char *pkgname)
271 pkginfo *info = NULL;
278 char *saveptr = NULL;
284 fd = open(RPM_PKG_INFO, O_CREAT | O_RDWR, 0644);
286 _d_msg(DEBUG_ERR, "open failed\n");
290 err = __ri_xsystem_with_dup(pkgname, fd);
292 "[_rpm_installer_get_pkg_info] _xsystem returns %d\n", err);
295 "[_rpm_installer_get_pkg_info] "
296 "Package Not installed \n");
299 } else if (err == 2) {
301 "[_rpm_installer_get_pkg_info] "
302 "package already install\n");
303 info = malloc(sizeof(pkginfo));
305 _d_msg(DEBUG_ERR, "Malloc Failed\n");
309 memset(info, 0x00, sizeof(pkginfo));
311 fp = fopen(RPM_PKG_INFO, "r");
313 _d_msg(DEBUG_ERR, "fopen failed\n");
317 /* Now open file and get pkgname and version */
318 while ((read = getline(&line, &len, fp)) != -1) {
319 int len = strlen(line);
320 line[len - 1] = '\0';
322 _d_msg(DEBUG_INFO, "line[%s]\n", line);
324 tok = strtok_r(line, " ", &saveptr); /*Name */
325 if (tok && strncmp(tok, "Name", 4) == 0) {
327 tok = strtok_r(NULL, " ", &saveptr);
329 tok = strtok_r(NULL, " ", &saveptr);
331 strncpy(info->package_name, tok,
332 sizeof(info->package_name));
334 } else if (tok && strncmp(tok, "Version", 7) == 0) {
336 tok = strtok_r(NULL, " ", &saveptr);
338 tok = strtok_r(NULL, " ", &saveptr);
340 strncpy(info->version, tok,
341 sizeof(info->version));
352 remove(RPM_PKG_INFO);
357 "[_rpm_installer_get_pkg_info] "
358 "_xsystem returns error = %d\n", err);
362 remove(RPM_PKG_INFO);
369 int _rpm_installer_package_install(char *pkgfilepath, bool forceinstall,
370 char *installoptions)
373 if (forceinstall == true && installoptions == NULL)
374 return RPM_INSTALLER_ERR_WRONG_PARAM;
375 pkginfo *info = NULL;
376 pkginfo *tmpinfo = NULL;
377 /*Check to see if the package is already installed or not
378 If it is installed, compare the versions. If the current version
379 is higher than the installed version, upgrade it automatically
380 else ask for user confirmation before downgrading */
382 info = _rpm_installer_get_pkgfile_info(pkgfilepath);
384 /* failed to get pkg info */
385 return RPM_INSTALLER_ERR_UNKNOWN;
388 _ri_set_backend_state_info(GOT_PACKAGE_INFO_SUCCESSFULLY);
393 gpkgname = strdup(info->package_name);
395 tmpinfo = _rpm_installer_get_pkgname_info(info->package_name);
396 if (tmpinfo == NULL) {
397 /* package is not installed. Go for installation. */
402 err = _rpm_install_pkg(pkgfilepath, installoptions);
405 "install complete with error(%d)\n", err);
408 _ri_set_backend_state_info(REQUEST_COMPLETED);
409 return RPM_INSTALLER_SUCCESS;
411 } else if (strcmp(info->version, tmpinfo->version) > 0) {
413 err = _rpm_upgrade_pkg(pkgfilepath, "--force");
416 "upgrade complete with error(%d)\n", err);
427 _ri_set_backend_state_info(REQUEST_COMPLETED);
436 return RPM_INSTALLER_SUCCESS;
438 } else if (strcmp(info->version, tmpinfo->version) < 0) {
439 /*show popup and confirm from user */
440 switch (do_upgrade) {
442 _ri_set_backend_state_info(REQUEST_PENDING);
443 // return RPM_INSTALLER_ERR_NEED_USER_CONFIRMATION;
444 return RPM_INSTALLER_ERR_PACKAGE_NOT_UPGRADED;
455 _ri_set_backend_state_info(REQUEST_COMPLETED);
456 return RPM_INSTALLER_ERR_PACKAGE_NOT_UPGRADED;
458 /*continue with downgrade */
459 _ri_set_backend_state_info
460 (GOT_PACKAGE_INFO_SUCCESSFULLY);
461 err = _rpm_upgrade_pkg(pkgfilepath, "--force");
464 "upgrade complete with error(%d)\n",
476 _ri_set_backend_state_info(REQUEST_COMPLETED);
485 return RPM_INSTALLER_SUCCESS;
490 /*same package. Reinstall it. Manifest should be parsed again */
491 err = _rpm_upgrade_pkg(pkgfilepath, "--force");
494 "upgrade complete with error(%d)\n", err);
505 _ri_set_backend_state_info(REQUEST_COMPLETED);
514 return RPM_INSTALLER_SUCCESS;
518 return RPM_INSTALLER_SUCCESS;
522 int _rpm_installer_package_uninstall(char *pkgname)
525 pkginfo *tmppkginfo = _rpm_installer_get_pkgname_info(pkgname);
526 if (tmppkginfo == NULL)
527 return RPM_INSTALLER_ERR_PACKAGE_NOT_INSTALLED;
537 gpkgname = strdup(pkgname);
538 _ri_broadcast_status_notification(pkgname, "start", "uninstall");
539 _ri_broadcast_status_notification(pkgname, "command", "Uninstall");
541 _ri_set_backend_state_info(GOT_PACKAGE_INFO_SUCCESSFULLY);
542 ret = _rpm_uninstall_pkg(pkgname);
544 _ri_set_backend_state_info(REQUEST_COMPLETED);
549 int _rpm_installer_clear_private_data(char *pkgname)
552 return RPM_INSTALLER_ERR_WRONG_PARAM;
553 char dir_path[256] = { '\0' };
555 snprintf(dir_path, 255, "/opt/apps/%s/data/", pkgname);
556 ret = __ri_recursive_delete_dir(dir_path);