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 /* For multi-user support */
45 #include <tzplatform_config.h>
47 /* SLP include files */
48 #include "rpm-installer.h"
49 #include "rpm-installer-util.h"
52 #define QUERY_PACKAGE "/usr/bin/query_rpm_package.sh"
53 #define RPM_PKG_INFO "/var/rpmpkg.info"
54 #define USER_APP_FOLDER tzplatform_getenv(TZ_USER_APP)
56 struct pkgfile_info_t {
60 typedef struct pkgfile_info_t pkgfile_info;
62 extern char *gpkgname;
63 extern int do_upgrade;
64 static int __ri_xsystem_with_dup(char *pkgid, int fd);
65 static int __ri_recursive_delete_dir(char *dirname);
67 static int __ri_recursive_delete_dir(char *dirname)
71 char abs_filename[FILENAME_MAX];
72 struct stat stFileInfo;
73 dp = opendir(dirname);
75 while (ep = readdir(dp)) {
76 snprintf(abs_filename, FILENAME_MAX, "%s/%s", dirname,
78 if (lstat(abs_filename, &stFileInfo) < 0)
80 if (S_ISDIR(stFileInfo.st_mode)) {
81 if (strcmp(ep->d_name, ".") &&
82 strcmp(ep->d_name, "..")) {
83 __ri_recursive_delete_dir(abs_filename);
92 _d_msg(DEBUG_ERR, "Couldn't open the directory\n");
93 return RPM_INSTALLER_ERR_CLEAR_DATA_FAILED;
96 return RPM_INSTALLER_SUCCESS;
99 pkginfo *_rpm_installer_get_pkgfile_info(char *pkgfile)
108 rpmVSFlags vsflags = 0;
109 pkginfo *info = NULL;
112 info = malloc(sizeof(pkginfo));
114 _d_msg(DEBUG_ERR, "Malloc Failed\n");
121 fd = Fopen(pkgfile, "r.ufdio");
122 if ((!fd) || Ferror(fd)) {
123 _d_msg(DEBUG_ERR, "Failed to open package file (%s)\n", Fstrerror(fd));
132 vsflags |= _RPMVSF_NODIGESTS;
133 vsflags |= _RPMVSF_NOSIGNATURES;
134 vsflags |= RPMVSF_NOHDRCHK;
135 (void) rpmtsSetVSFlags(ts, vsflags);
137 rc = rpmReadPackageFile(ts, fd, pkgfile, &hdr);
138 if (rc != RPMRC_OK) {
139 _d_msg(DEBUG_ERR, "Could not read package file\n");
146 headerGet(hdr, RPMTAG_NAME, td, HEADERGET_MINMEM);
147 strncpy(info->package_name, rpmtdGetString(td), sizeof(info->package_name) - 1);
148 _d_msg(DEBUG_INFO, "Package Name : %s\n", info->package_name);
151 headerGet(hdr, RPMTAG_VERSION, td, HEADERGET_MINMEM);
152 strncpy(info->version, rpmtdGetString(td), sizeof(info->version) - 1);
153 _d_msg(DEBUG_INFO, "Version : %s\n", info->version);
166 pkginfo *_rpm_installer_get_pkgname_info(char *pkgid)
171 rpmdbMatchIterator mi;
174 pkginfo *info = NULL;
177 info = malloc(sizeof(pkginfo));
179 _d_msg(DEBUG_ERR, "Malloc Failed\n");
187 mi = rpmtsInitIterator(ts, RPMDBI_PACKAGES, NULL, 0);
188 while (NULL != (hdr = rpmdbNextIterator(mi))) {
190 hdr = headerLink(hdr);
191 rc = headerGet(hdr, RPMTAG_NAME, tn, HEADERGET_MINMEM);
192 if (strcmp(pkgid, rpmtdGetString(tn)) == 0) {
203 _d_msg(DEBUG_ERR, "Package not found in DB\n");
209 headerGet(hdr, RPMTAG_NAME, tn, HEADERGET_MINMEM);
210 strncpy(info->package_name, rpmtdGetString(tn),
211 sizeof(info->package_name)-1);
212 _d_msg(DEBUG_INFO, "Package Name : %s\n", info->package_name);
214 headerGet(hdr, RPMTAG_VERSION, tv, HEADERGET_MINMEM);
215 strncpy(info->version, rpmtdGetString(tv), sizeof(info->version)-1);
216 _d_msg(DEBUG_INFO, "Version : %s\n", info->version);
225 rpmdbFreeIterator(mi);
234 static int __ri_xsystem_with_dup(char *pkgname, int fd)
238 const char *argv[] = { QUERY_PACKAGE, pkgname, NULL };
242 perror("fork failed");
248 dup(fd); /* dup called twice to create copy of fd 1 and fd 2 */
249 execvp(argv[0], (char *const *)argv);
254 if (waitpid(pid, &status, 0) == -1) {
255 perror("waitpid failed");
258 if (WIFSIGNALED(status)) {
260 printf("sig no. %d\n", WTERMSIG(status));
263 if (!WIFEXITED(status)) {
264 perror("should not happen");
268 return WEXITSTATUS(status);
271 pkginfo *_rpm_installer_get_pkg_info(char *pkgname)
273 pkginfo *info = NULL;
280 char *saveptr = NULL;
286 fd = open(RPM_PKG_INFO, O_CREAT | O_RDWR, 0644);
288 _d_msg(DEBUG_ERR, "open failed\n");
292 err = __ri_xsystem_with_dup(pkgname, fd);
294 "[_rpm_installer_get_pkg_info] _xsystem returns %d\n", err);
297 "[_rpm_installer_get_pkg_info] "
298 "Package Not installed \n");
301 } else if (err == 2) {
303 "[_rpm_installer_get_pkg_info] "
304 "package already install\n");
305 info = malloc(sizeof(pkginfo));
307 _d_msg(DEBUG_ERR, "Malloc Failed\n");
311 memset(info, 0x00, sizeof(pkginfo));
313 fp = fopen(RPM_PKG_INFO, "r");
315 _d_msg(DEBUG_ERR, "fopen failed\n");
319 /* Now open file and get pkgname and version */
320 while ((read = getline(&line, &len, fp)) != -1) {
321 int len = strlen(line);
322 line[len - 1] = '\0';
324 _d_msg(DEBUG_INFO, "line[%s]\n", line);
326 tok = strtok_r(line, " ", &saveptr); /*Name */
327 if (tok && strncmp(tok, "Name", 4) == 0) {
329 tok = strtok_r(NULL, " ", &saveptr);
331 tok = strtok_r(NULL, " ", &saveptr);
333 strncpy(info->package_name, tok,
334 sizeof(info->package_name));
336 } else if (tok && strncmp(tok, "Version", 7) == 0) {
338 tok = strtok_r(NULL, " ", &saveptr);
340 tok = strtok_r(NULL, " ", &saveptr);
342 strncpy(info->version, tok,
343 sizeof(info->version));
354 remove(RPM_PKG_INFO);
359 "[_rpm_installer_get_pkg_info] "
360 "_xsystem returns error = %d\n", err);
364 remove(RPM_PKG_INFO);
371 int _rpm_installer_package_install(char *pkgfilepath, bool forceinstall,
372 char *installoptions)
375 if (forceinstall == true && installoptions == NULL)
376 return RPM_INSTALLER_ERR_WRONG_PARAM;
377 pkginfo *info = NULL;
378 pkginfo *tmpinfo = NULL;
379 /*Check to see if the package is already installed or not
380 If it is installed, compare the versions. If the current version
381 is higher than the installed version, upgrade it automatically
382 else ask for user confirmation before downgrading */
384 info = _rpm_installer_get_pkgfile_info(pkgfilepath);
386 /* failed to get pkg info */
387 return RPM_INSTALLER_ERR_UNKNOWN;
390 _ri_set_backend_state_info(GOT_PACKAGE_INFO_SUCCESSFULLY);
395 gpkgname = strdup(info->package_name);
397 tmpinfo = _rpm_installer_get_pkgname_info(info->package_name);
398 if (tmpinfo == NULL) {
399 /* package is not installed. Go for installation. */
404 err = _rpm_install_pkg(pkgfilepath, installoptions);
407 "install complete with error(%d)\n", err);
410 _ri_set_backend_state_info(REQUEST_COMPLETED);
411 return RPM_INSTALLER_SUCCESS;
413 } else if (strcmp(info->version, tmpinfo->version) > 0) {
415 err = _rpm_upgrade_pkg(pkgfilepath, "--force");
418 "upgrade complete with error(%d)\n", err);
429 _ri_set_backend_state_info(REQUEST_COMPLETED);
438 return RPM_INSTALLER_SUCCESS;
440 } else if (strcmp(info->version, tmpinfo->version) < 0) {
441 /*show popup and confirm from user */
442 switch (do_upgrade) {
444 _ri_set_backend_state_info(REQUEST_PENDING);
453 return RPM_INSTALLER_ERR_NEED_USER_CONFIRMATION;
464 _ri_set_backend_state_info(REQUEST_COMPLETED);
465 return RPM_INSTALLER_ERR_PACKAGE_NOT_UPGRADED;
467 /*continue with downgrade */
468 _ri_set_backend_state_info
469 (GOT_PACKAGE_INFO_SUCCESSFULLY);
470 err = _rpm_upgrade_pkg(pkgfilepath, "--force");
473 "upgrade complete with error(%d)\n",
485 _ri_set_backend_state_info(REQUEST_COMPLETED);
494 return RPM_INSTALLER_SUCCESS;
499 /*same package. Reinstall it. Manifest should be parsed again */
500 err = _rpm_upgrade_pkg(pkgfilepath, "--force");
503 "upgrade complete with error(%d)\n", err);
514 _ri_set_backend_state_info(REQUEST_COMPLETED);
523 return RPM_INSTALLER_SUCCESS;
534 return RPM_INSTALLER_SUCCESS;
538 int _rpm_installer_package_uninstall(char *pkgid)
541 pkginfo *tmppkginfo = _rpm_installer_get_pkgname_info(pkgid);
542 if (tmppkginfo == NULL)
543 return RPM_INSTALLER_ERR_PACKAGE_NOT_INSTALLED;
553 gpkgname = strdup(pkgid);
554 _ri_broadcast_status_notification(pkgid, "start", "uninstall");
555 _ri_broadcast_status_notification(pkgid, "command", "Uninstall");
557 _ri_set_backend_state_info(GOT_PACKAGE_INFO_SUCCESSFULLY);
558 ret = _rpm_uninstall_pkg(pkgid);
560 _ri_set_backend_state_info(REQUEST_COMPLETED);
565 int _rpm_installer_clear_private_data(char *pkgid)
568 return RPM_INSTALLER_ERR_WRONG_PARAM;
570 char dir_path[256] = { '\0' };
573 snprintf(dir_path, 255, "%s/%s/data/", USER_APP_FOLDER, pkgid);
574 ret = __ri_recursive_delete_dir(dir_path);