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>
41 /* SLP include files */
42 #include <pkgmgr-info.h>
43 #include <pkgmgr_parser.h>
44 #include "rpm-installer.h"
45 #include "rpm-installer-type.h"
46 #include "rpm-installer-util.h"
48 #include "rpm-frontend.h"
51 extern char *gpkgname;
52 extern int do_upgrade;
54 char* _rpm_load_directory(char *directory,char* pkgfile)
57 struct dirent entry, *result;
61 // char *rpm_pkgname = NULL;
62 char xml_file[PATH_MAX] = {0};
64 buf = malloc(BUF_SIZE);
66 _LOGE("malloc failed.\n");
70 dir = opendir(directory);
72 if (strerror_r(errno, buf, BUF_SIZE) == 0)
73 _LOGE("Can not access to the [%s] because %s.\n", directory, buf);
78 _LOGD("Loading manifest files from %s\n", directory);
80 for (ret = readdir_r(dir, &entry, &result);
81 ret == 0 && result != NULL;
82 ret = readdir_r(dir, &entry, &result)) {
83 char *manifest = NULL;
85 if (!strcmp(entry.d_name, ".") ||
86 !strcmp(entry.d_name, "..")) {
90 manifest = _manifest_to_package(entry.d_name);
92 _LOGE("Failed to convert file to xml[%s].\n", entry.d_name);
96 memset(xml_file, '\0', PATH_MAX);
97 snprintf(xml_file,PATH_MAX-1,"%s/%s",directory,manifest);
98 _LOGD("manifest is [%s] and its full path is [%s]",manifest,xml_file);
99 ret = _get_package_name_from_xml(xml_file,&pkgname);
100 if(ret != PMINFO_R_OK || pkgname == NULL){
101 _LOGE("Unable To read [%s] manifest file",xml_file);
108 snprintf(buf, BUF_SIZE, "%s/%s", directory, manifest);
109 _LOGD("Manifest file is %s\n",manifest);
114 #if 0 //dont check pkgname from rpm-name, there is a bug
115 ret = _get_pkgname_from_rpm_name(pkgfile, &rpm_pkgname);
116 if(ret != RPM_INSTALLER_SUCCESS || rpm_pkgname == NULL){
117 _LOGE("Couldn't get the pkgname from rpm file [%s]",pkgfile);
130 _LOGD("Pkgname from xml is [%s] and pkgname from rpm's name is [%s]",pkgname,rpm_pkgname);
133 Compare the package name which is extracted from manifest file with package name which is extracted from rpm file's name.
134 If match is successful then it is required manifest file.
137 if(!strcmp(pkgname,rpm_pkgname)){
138 snprintf(buf, BUF_SIZE, "%s/%s", directory, manifest);
139 _LOGD("Manifest file is %s\n",buf);
172 pkginfo *_rpm_installer_get_pkgfile_info(char *pkgfile)
174 pkginfo *info = NULL;
175 manifest_x *mfx = NULL;
178 char cwd[BUF_SIZE] = {'\0'};
179 char buff[BUF_SIZE] = {'\0'};
180 char manifest[BUF_SIZE] = { '\0'};
183 temp = getcwd(cwd, BUF_SIZE);
184 if ((temp == NULL) || (cwd[0] == '\0')) {
185 _LOGE("getcwd() failed.\n");
189 ret = mkdir(TEMP_DIR, 0644);
191 if (access(TEMP_DIR, F_OK) == 0) {
192 _rpm_delete_dir(TEMP_DIR);
193 ret = mkdir(TEMP_DIR, 0644);
195 _LOGE("mkdir() failed.\n");
199 _LOGE("mkdir() failed.\n");
204 ret = chdir(TEMP_DIR);
206 _LOGE("chdir(%s) failed [%s].\n", TEMP_DIR, strerror(errno));
210 _LOGD("switched to %s\n", TEMP_DIR);
212 const char *cpio_argv[] = { CPIO_SCRIPT, pkgfile, NULL };
213 ret = _ri_xsystem(cpio_argv);
215 snprintf(manifest, BUF_SIZE, "%s/opt/share/packages", TEMP_DIR);
216 char* manifestpath = _rpm_load_directory(manifest,pkgfile);
217 if (manifestpath != NULL) {
218 strncpy(buff, manifestpath, sizeof(buff) - 1);
222 if (buff[0] == '\0') {
223 snprintf(manifest, BUF_SIZE, "%s/usr/share/packages", TEMP_DIR);
224 manifestpath = _rpm_load_directory(manifest,pkgfile);
225 if (manifestpath != NULL) {
226 strncpy(buff, manifestpath, sizeof(buff) - 1);
230 if (buff[0] == '\0') {
239 _LOGD("Manifest file is [%s]",buff);
243 _LOGD("The path of manifest.xml is %s.\n", buff);
245 /*get package name from xml*/
246 mfx = pkgmgr_parser_process_manifest_xml(buff);
249 info = calloc(1, sizeof(pkginfo));
251 _LOGE("calloc failed.\n");
255 strncpy(info->package_name, mfx->package, sizeof(info->package_name) - 1);
256 strncpy(info->version, mfx->version, sizeof(info->version) - 1);
257 _LOGD("_rpm_installer_get_pkgfile_info, pkgname: (%s), version(%s)\n", info->package_name, info->version);
262 _rpm_delete_dir(TEMP_DIR);
266 _LOGE("chdir(%s) failed [%s].\n", cwd, strerror(errno));
270 pkgmgr_parser_free_manifest_xml(mfx);
276 pkginfo *_rpm_installer_get_pkgname_info(const char *pkgid)
278 pkginfo *info = NULL;
280 char *packageid = NULL;
281 char *version = NULL;
282 pkgmgrinfo_pkginfo_h handle = NULL;
285 _LOGE("pkgid is NULL.\n");
289 info = malloc(sizeof(pkginfo));
291 _LOGE("malloc failed.\n");
295 ret = pkgmgrinfo_pkginfo_get_pkginfo(pkgid, &handle);
296 if (ret != PMINFO_R_OK || handle == NULL) {
297 _LOGE("fisrt installation, pkgid=[%s]", pkgid);
302 ret = pkgmgrinfo_pkginfo_get_pkgid(handle, &packageid);
303 if (ret != PMINFO_R_OK) {
304 _LOGE("failed to get the pkgid.\n");
307 strncpy(info->package_name, packageid, sizeof(info->package_name) - 1);
309 ret = pkgmgrinfo_pkginfo_get_version(handle, &version);
310 if (ret != PMINFO_R_OK) {
311 _LOGE("failed to get the version.\n");
314 strncpy(info->version, version, sizeof(info->version) - 1);
316 pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
318 _LOGD("pkgid=[%s], version=[%s]", info->package_name, info->version);
327 pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
331 int _rpm_installer_corexml_install(char *pkgfilepath)
333 /* Get package ID from filepath <pkgid.xml>*/
339 temp = strdup(pkgfilepath);
341 return RPM_INSTALLER_ERR_NOT_ENOUGH_MEMORY;
342 p = strrchr(temp, '/');
347 return RPM_INSTALLER_ERR_INTERNAL;
349 /*p now points to pkgid.xml*/
352 _LOGE("Failed to extract pkgid from xml name\n");
354 return RPM_INSTALLER_ERR_INTERNAL;
356 idx = strlen(p) - strlen(q);
358 _LOGD("package id is [%s]", p);
359 ret = _rpm_install_corexml(pkgfilepath, p);
364 int _rpm_installer_package_install(char *pkgfilepath, bool forceinstall,
365 char *installoptions, char *clientid)
369 if (forceinstall == true && installoptions == NULL)
370 return RPM_INSTALLER_ERR_WRONG_PARAM;
372 /* Check for core xml installation */
373 p = strrchr(pkgfilepath, '.');
375 if (strncmp(p+1, "xml", 3) == 0) {
376 err = _rpm_installer_corexml_install(pkgfilepath);
378 _LOGE("_rpm_installer_corexml_install() failed\n");
380 _LOGE("_rpm_installer_corexml_install() success\n");
385 _LOGE("pkgfilepath does not have an extension\n");
386 return RPM_INSTALLER_ERR_INTERNAL;
388 /* rpm installation */
389 pkginfo *info = NULL;
390 pkginfo *tmpinfo = NULL;
391 /*Check to see if the package is already installed or not
392 If it is installed, compare the versions. If the current version
393 is higher than the installed version, upgrade it automatically
394 else ask for user confirmation before downgrading */
396 info = _rpm_installer_get_pkgfile_info(pkgfilepath);
398 /* failed to get pkg info */
399 return RPM_INSTALLER_ERR_INTERNAL;
402 _ri_set_backend_state_info(GOT_PACKAGE_INFO_SUCCESSFULLY);
403 _ri_save_last_input_info(pkgfilepath,INSTALL_CMD,0);
408 gpkgname = strdup(info->package_name);
409 if(gpkgname == NULL){
410 _LOGE("Malloc failed!!");
415 return RPM_INSTALLER_ERR_INTERNAL;
418 tmpinfo = _rpm_installer_get_pkgname_info(info->package_name);
419 if (tmpinfo == NULL) {
420 _LOGD("tmpinfo is null.\n");
422 /* package is not installed. Go for installation. */
428 err = _rpm_install_pkg_with_dbpath(pkgfilepath, gpkgname, clientid);
431 "install complete with error(%d)\n", err);
434 _ri_set_backend_state_info(REQUEST_COMPLETED);
435 return RPM_INSTALLER_SUCCESS;
437 } else if (strcmp(info->version, tmpinfo->version) > 0) {
440 _LOGD("[upgrade] %s, %s\n", info->version, tmpinfo->version);
442 err = _rpm_upgrade_pkg_with_dbpath(pkgfilepath, gpkgname);
445 "upgrade complete with error(%d)\n", err);
456 _ri_set_backend_state_info(REQUEST_COMPLETED);
465 return RPM_INSTALLER_SUCCESS;
467 } else if (strcmp(info->version, tmpinfo->version) < 0) {
469 _LOGD("[down grade] %s, %s\n", info->version, tmpinfo->version);
471 err = _rpm_upgrade_pkg_with_dbpath(pkgfilepath, gpkgname);
474 "upgrade complete with error(%d)\n",
486 _ri_set_backend_state_info(REQUEST_COMPLETED);
495 return RPM_INSTALLER_SUCCESS;
500 /*same package. Reinstall it. Manifest should be parsed again */
502 _LOGD("[same pkg] %s, %s\n", info->package_name, info->version);
504 err = _rpm_upgrade_pkg_with_dbpath(pkgfilepath, gpkgname);
507 "upgrade complete with error(%d)\n", err);
518 _ri_set_backend_state_info(REQUEST_COMPLETED);
527 return RPM_INSTALLER_SUCCESS;
531 return RPM_INSTALLER_SUCCESS;
535 int _rpm_installer_package_install_with_dbpath(char *pkgfilepath, char *clientid)
538 pkginfo *info = NULL;
539 pkginfo *tmpinfo = NULL;
541 /*Check to see if the package is already installed or not
542 If it is installed, compare the versions. If the current version
543 is higher than the installed version, upgrade it automatically
544 else ask for user confirmation before downgrading */
546 _LOGD("[##]start : _rpm_installer_package_install_with_dbpath\n");
548 info = _rpm_installer_get_pkgfile_info(pkgfilepath);
550 _LOGE("@Failed to get pkg info.\n");
551 /* failed to get pkg info */
552 return RPM_INSTALLER_ERR_INTERNAL;
555 _ri_set_backend_state_info(GOT_PACKAGE_INFO_SUCCESSFULLY);
556 _ri_save_last_input_info(info->package_name,EFLWGT_INSTALL_CMD,0);
561 gpkgname = strdup(info->package_name);
562 if(gpkgname == NULL){
563 _LOGE("Malloc failed!!");
568 return RPM_INSTALLER_ERR_INTERNAL;
571 tmpinfo = _rpm_installer_get_pkgname_info(info->package_name);
572 if (tmpinfo == NULL) {
573 /* package is not installed. Go for installation. */
574 _LOGD("#package is not installed. Go for installation\n");
575 ret = _rpm_install_pkg_with_dbpath(pkgfilepath, info->package_name, clientid);
577 } else if (strcmp(info->version, tmpinfo->version) > 0) {
579 _LOGD("#package is installed. Go for upgrade\n");
580 ret = _rpm_upgrade_pkg_with_dbpath(pkgfilepath, info->package_name);
581 } else if (strcmp(info->version, tmpinfo->version) < 0) {
583 _LOGD("#package is installed. Go for upgrade\n");
584 ret = _rpm_upgrade_pkg_with_dbpath(pkgfilepath, info->package_name);
587 /*same package. Reinstall it. Manifest should be parsed again */
588 _LOGD( "#package is same. Go for reinstall(upgrade)\n");
589 ret = _rpm_upgrade_pkg_with_dbpath(pkgfilepath, info->package_name);
602 _LOGE("[@@]end : _rpm_installer_package_install_with_dbpath(%d)\n", ret);
604 _LOGD( "[##]end : _rpm_installer_package_install_with_dbpath \n");
610 int _rpm_installer_package_uninstall_with_dbpath(const char *pkgid)
612 return _rpm_uninstall_pkg_with_dbpath(pkgid, 0);
615 int _rpm_installer_package_uninstall(char *pkgid)
619 _LOGD( "start : _rpm_installer_package_uninstall\n");
621 pkginfo *tmppkginfo = _rpm_installer_get_pkgname_info(pkgid);
622 if (tmppkginfo == NULL) {
623 _LOGE("tmppkginfo is NULL.\n");
624 return RPM_INSTALLER_ERR_PACKAGE_NOT_INSTALLED;
636 gpkgname = strdup(pkgid);
637 // _ri_broadcast_status_notification(pkgid, "command", "Uninstall");
639 _ri_set_backend_state_info(GOT_PACKAGE_INFO_SUCCESSFULLY);
640 _ri_save_last_input_info(pkgid,DELETE_CMD,0);
641 ret = _rpm_uninstall_pkg(pkgid);
643 _ri_set_backend_state_info(REQUEST_COMPLETED);
645 _LOGD("end : _rpm_installer_package_uninstall(%d)\n", ret);
650 int _rpm_installer_clear_private_data(char *pkgid)
653 return RPM_INSTALLER_ERR_WRONG_PARAM;
654 char dir_path[BUF_SIZE] = { '\0' };
656 snprintf(dir_path, 255, "/opt/usr/apps/%s/data/", pkgid);
657 ret = _ri_recursive_delete_dir(dir_path);