Git-Url: http://git.frugalware.org/gitweb/gitweb.cgi?p=pacman-g2.git;a=commitdiff;h=0664e5834a036d7270c81a07412bb996db2a8249
commit 0664e5834a036d7270c81a07412bb996db2a8249 Author: Michel Hermier <[email protected]> Date: Thu Apr 4 08:55:14 2013 +0200 libpacman: Merge lasts bits of add.c in trans.c. diff --git a/lib/libpacman/Makefile.am b/lib/libpacman/Makefile.am index 9d964be..ef19002 100644 --- a/lib/libpacman/Makefile.am +++ b/lib/libpacman/Makefile.am @@ -28,7 +28,6 @@ TARGETS = md5driver.c \ packages_transaction.c \ trans.c \ trans_sysupgrade.c \ - add.c \ remove.c \ sync.c \ handle.c \ diff --git a/lib/libpacman/add.c b/lib/libpacman/add.c deleted file mode 100644 index 0bea105..0000000 --- a/lib/libpacman/add.c +++ /dev/null @@ -1,608 +0,0 @@ -/* - * add.c - * - * Copyright (c) 2002-2006 by Judd Vinet <[email protected]> - * Copyright (c) 2005 by Aurelien Foret <[email protected]> - * Copyright (c) 2005 by Christian Hamar <[email protected]> - * Copyright (c) 2006 by David Kimpe <[email protected]> - * Copyright (c) 2005, 2006 by Miklos Vajna <[email protected]> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - * USA. - */ - -#include "config.h" - -#if defined(__APPLE__) || defined(__OpenBSD__) -#include <sys/syslimits.h> -#endif -#if defined(__APPLE__) || defined(__OpenBSD__) || defined(__sun__) -#include <sys/stat.h> -#endif - -#include <stdlib.h> -#include <errno.h> -#include <time.h> -#include <fcntl.h> -#include <string.h> -#include <limits.h> - -/* pacman-g2 */ -#include "add.h" - -#include "trans.h" -#include "util.h" -#include "error.h" -#include "cache.h" -#include "deps.h" -#include "versioncmp.h" -#include "md5.h" -#include "sha1.h" -#include "log.h" -#include "backup.h" -#include "package.h" -#include "db.h" -#include "provide.h" -#include "conflict.h" -#include "add.h" -#include "remove.h" -#include "handle.h" -#include "packages_transaction.h" - -int _pacman_add_commit(pmtrans_t *trans, pmlist_t **data) -{ - int i, ret = 0, errors = 0, needdisp = 0; - int remain, howmany, archive_ret; - double percent; - register struct archive *archive; - struct archive_entry *entry; - char expath[PATH_MAX], cwd[PATH_MAX] = "", *what; - unsigned char cb_state; - time_t t; - pmlist_t *targ, *lp; - pmdb_t *db = trans->handle->db_local; - - ASSERT(trans != NULL, RET_ERR(PM_ERR_TRANS_NULL, -1)); - ASSERT(db != NULL, RET_ERR(PM_ERR_DB_NULL, -1)); - - if(trans->_packages == NULL) { - return(0); - } - - for(targ = trans->_packages; targ; targ = targ->next) { - unsigned short pmo_upgrade; - char pm_install[PATH_MAX]; - pmpkg_t *info = (pmpkg_t *)targ->data; - pmpkg_t *oldpkg = NULL; - errors = 0; - remain = _pacman_list_count(targ); - howmany = _pacman_list_count(trans->_packages); - - if(handle->trans->state == STATE_INTERRUPTED) { - break; - } - - pmo_upgrade = (trans->type == PM_TRANS_TYPE_UPGRADE) ? 1 : 0; - - /* see if this is an upgrade. if so, remove the old package first */ - if(pmo_upgrade) { - pmpkg_t *local = _pacman_db_get_pkgfromcache(db, info->name); - if(local) { - EVENT(trans, PM_TRANS_EVT_UPGRADE_START, info, NULL); - cb_state = PM_TRANS_PROGRESS_UPGRADE_START; - _pacman_log(PM_LOG_FLOW1, _("upgrading package %s-%s"), info->name, info->version); - if((what = (char *)malloc(strlen(info->name)+1)) == NULL) { - RET_ERR(PM_ERR_MEMORY, -1); - } - STRNCPY(what, info->name, strlen(info->name)+1); - - /* we'll need to save some record for backup checks later */ - oldpkg = _pacman_pkg_new(local->name, local->version); - if(oldpkg) { - if(!(local->infolevel & INFRQ_FILES)) { - _pacman_log(PM_LOG_DEBUG, _("loading FILES info for '%s'"), local->name); - _pacman_db_read(db, INFRQ_FILES, local); - } - oldpkg->backup = _pacman_strlist_dup(local->backup); - strncpy(oldpkg->name, local->name, PKG_NAME_LEN); - strncpy(oldpkg->version, local->version, PKG_VERSION_LEN); - } - - /* pre_upgrade scriptlet */ - if(info->scriptlet && !(trans->flags & PM_TRANS_FLAG_NOSCRIPTLET)) { - _pacman_runscriptlet(handle->root, info->data, "pre_upgrade", info->version, oldpkg ? oldpkg->version : NULL, - trans); - } - - if(oldpkg) { - pmtrans_t *tr; - _pacman_log(PM_LOG_FLOW1, _("removing old package first (%s-%s)"), oldpkg->name, oldpkg->version); - tr = _pacman_trans_new(); - if(tr == NULL) { - RET_ERR(PM_ERR_TRANS_ABORT, -1); - } - pmtrans_cbs_t null_cbs = { NULL }; - if(_pacman_trans_init(tr, PM_TRANS_TYPE_UPGRADE, trans->flags, null_cbs) == -1) { - FREETRANS(tr); - RET_ERR(PM_ERR_TRANS_ABORT, -1); - } - if(_pacman_trans_addtarget(tr, info->name, PM_TRANS_TYPE_REMOVE, 0) == -1) { - FREETRANS(tr); - RET_ERR(PM_ERR_TRANS_ABORT, -1); - } - /* copy the skiplist over */ - tr->skiplist = _pacman_strlist_dup(trans->skiplist); - if(_pacman_remove_commit(tr, NULL) == -1) { - FREETRANS(tr); - RET_ERR(PM_ERR_TRANS_ABORT, -1); - } - FREETRANS(tr); - } - } else { - /* no previous package version is installed, so this is actually - * just an install. */ - pmo_upgrade = 0; - } - } - if(!pmo_upgrade) { - EVENT(trans, PM_TRANS_EVT_ADD_START, info, NULL); - cb_state = PM_TRANS_PROGRESS_ADD_START; - _pacman_log(PM_LOG_FLOW1, _("adding package %s-%s"), info->name, info->version); - if((what = (char *)malloc(strlen(info->name)+1)) == NULL) { - RET_ERR(PM_ERR_MEMORY, -1); - } - STRNCPY(what, info->name, strlen(info->name)+1); - - /* pre_install scriptlet */ - if(info->scriptlet && !(trans->flags & PM_TRANS_FLAG_NOSCRIPTLET)) { - _pacman_runscriptlet(handle->root, info->data, "pre_install", info->version, NULL, trans); - } - } else { - _pacman_log(PM_LOG_FLOW1, _("adding new package %s-%s"), info->name, info->version); - } - - if(!(trans->flags & PM_TRANS_FLAG_DBONLY)) { - _pacman_log(PM_LOG_FLOW1, _("extracting files")); - - /* Extract the package */ - if ((archive = archive_read_new ()) == NULL) - RET_ERR(PM_ERR_LIBARCHIVE_ERROR, -1); - - archive_read_support_compression_all (archive); - archive_read_support_format_all (archive); - - if (archive_read_open_file (archive, info->data, PM_DEFAULT_BYTES_PER_BLOCK) != ARCHIVE_OK) { - RET_ERR(PM_ERR_PKG_OPEN, -1); - } - - /* save the cwd so we can restore it later */ - if(getcwd(cwd, PATH_MAX) == NULL) { - _pacman_log(PM_LOG_ERROR, _("could not get current working directory")); - /* in case of error, cwd content is undefined: so we set it to something */ - cwd[0] = 0; - } - - /* libarchive requires this for extracting hard links */ - chdir(handle->root); - - for(i = 0; (archive_ret = archive_read_next_header (archive, &entry)) == ARCHIVE_OK; i++) { - int nb = 0; - int notouch = 0; - char *md5_orig = NULL; - char *sha1_orig = NULL; - char pathname[PATH_MAX]; - struct stat buf; - - STRNCPY(pathname, archive_entry_pathname (entry), PATH_MAX); - - if (info->size != 0) - percent = (double)archive_position_uncompressed(archive) / info->size; - if (needdisp == 0) { - PROGRESS(trans, cb_state, what, (int)(percent * 100), howmany, (howmany - remain +1)); - } - - if(!strcmp(pathname, ".PKGINFO") || !strcmp(pathname, ".FILELIST")) { - archive_read_data_skip (archive); - continue; - } - - /*if(!strcmp(pathname, "._install") || !strcmp(pathname, ".INSTALL")) { - * the install script goes inside the db - * snprintf(expath, PATH_MAX, "%s/%s-%s/install", db->path, info->name, info->version); */ - if(!strcmp(pathname, "._install") || !strcmp(pathname, ".INSTALL") || - !strcmp(pathname, ".CHANGELOG")) { - if(!strcmp(pathname, ".CHANGELOG")) { - /* the changelog goes inside the db */ - snprintf(expath, PATH_MAX, "%s/%s-%s/changelog", db->path, - info->name, info->version); - } else { - /* the install script goes inside the db */ - snprintf(expath, PATH_MAX, "%s/%s-%s/install", db->path, - info->name, info->version); - } - } else { - /* build the new pathname relative to handle->root */ - snprintf(expath, PATH_MAX, "%s%s", handle->root, pathname); - if(expath[strlen(expath)-1] == '/') { - expath[strlen(expath)-1] = '\0'; - } - } - - /* if a file is in NoExtract then we never extract it. - * - * eg, /home/httpd/html/index.html may be removed so index.php - * could be used. - */ - if(_pacman_strlist_find(handle->noextract, pathname)) { - pacman_logaction(_("notice: %s is in NoExtract -- skipping extraction"), pathname); - archive_read_data_skip (archive); - continue; - } - - if(!lstat(expath, &buf)) { - /* file already exists */ - if(S_ISLNK(buf.st_mode)) { - continue; - } else if(!S_ISDIR(buf.st_mode)) { - if(_pacman_strlist_find(handle->noupgrade, pathname)) { - notouch = 1; - } else { - if(!pmo_upgrade || oldpkg == NULL) { - nb = _pacman_strlist_find(info->backup, pathname); - } else { - /* op == PM_TRANS_TYPE_UPGRADE */ - md5_orig = _pacman_needbackup(pathname, oldpkg->backup); - sha1_orig = _pacman_needbackup(pathname, oldpkg->backup); - if(md5_orig || sha1_orig) { - nb = 1; - } - } - } - } - } - - if(nb) { - char *temp; - char *md5_local, *md5_pkg; - char *sha1_local, *sha1_pkg; - int fd; - - /* extract the package's version to a temporary file and md5 it */ - temp = strdup("/tmp/pacman_XXXXXX"); - fd = mkstemp(temp); - - archive_entry_set_pathname (entry, temp); - - if(archive_read_extract (archive, entry, ARCHIVE_EXTRACT_FLAGS) != ARCHIVE_OK) { - _pacman_log(PM_LOG_ERROR, _("could not extract %s (%s)"), pathname, strerror(errno)); - pacman_logaction(_("could not extract %s (%s)"), pathname, strerror(errno)); - errors++; - unlink(temp); - FREE(temp); - FREE(md5_orig); - FREE(sha1_orig); - close(fd); - continue; - } - md5_local = _pacman_MDFile(expath); - md5_pkg = _pacman_MDFile(temp); - sha1_local = _pacman_SHAFile(expath); - sha1_pkg = _pacman_SHAFile(temp); - /* append the new md5 or sha1 hash to it's respective entry in info->backup - * (it will be the new orginal) - */ - for(lp = info->backup; lp; lp = lp->next) { - char *fn; - char *file = lp->data; - - if(!file) continue; - if(!strcmp(file, pathname)) { - if(info->sha1sum != NULL && info->sha1sum != '\0') { - /* 32 for the hash, 1 for the terminating NULL, and 1 for the tab delimiter */ - if((fn = (char *)malloc(strlen(file)+34)) == NULL) { - RET_ERR(PM_ERR_MEMORY, -1); - } - sprintf(fn, "%s\t%s", file, md5_pkg); - FREE(file); - lp->data = fn; - } else { - /* 41 for the hash, 1 for the terminating NULL, and 1 for the tab delimiter */ - if((fn = (char *)malloc(strlen(file)+43)) == NULL) { - RET_ERR(PM_ERR_MEMORY, -1); - } - sprintf(fn, "%s\t%s", file, sha1_pkg); - FREE(file); - lp->data = fn; - } - } - } - - if (info->sha1sum != NULL && info->sha1sum != '\0') { - _pacman_log(PM_LOG_DEBUG, _("checking md5 hashes for %s"), pathname); - _pacman_log(PM_LOG_DEBUG, _("current: %s"), md5_local); - _pacman_log(PM_LOG_DEBUG, _("new: %s"), md5_pkg); - if(md5_orig) { - _pacman_log(PM_LOG_DEBUG, _("original: %s"), md5_orig); - } - } else { - _pacman_log(PM_LOG_DEBUG, _("checking sha1 hashes for %s"), pathname); - _pacman_log(PM_LOG_DEBUG, _("current: %s"), sha1_local); - _pacman_log(PM_LOG_DEBUG, _("new: %s"), sha1_pkg); - if(sha1_orig) { - _pacman_log(PM_LOG_DEBUG, _("original: %s"), sha1_orig); - } - } - - if(!pmo_upgrade) { - /* PM_ADD */ - - /* if a file already exists with a different md5 or sha1 hash, - * then we rename it to a .pacorig extension and continue */ - if(strcmp(md5_local, md5_pkg) || strcmp(sha1_local, sha1_pkg)) { - char newpath[PATH_MAX]; - snprintf(newpath, PATH_MAX, "%s.pacorig", expath); - if(rename(expath, newpath)) { - archive_entry_set_pathname (entry, expath); - _pacman_log(PM_LOG_ERROR, _("could not rename %s (%s)"), pathname, strerror(errno)); - pacman_logaction(_("error: could not rename %s (%s)"), expath, strerror(errno)); - } - if(_pacman_copyfile(temp, expath)) { - archive_entry_set_pathname (entry, expath); - _pacman_log(PM_LOG_ERROR, _("could not copy %s to %s (%s)"), temp, pathname, strerror(errno)); - pacman_logaction(_("error: could not copy %s to %s (%s)"), temp, expath, strerror(errno)); - errors++; - } else { - archive_entry_set_pathname (entry, expath); - _pacman_log(PM_LOG_WARNING, _("%s saved as %s.pacorig"), pathname, pathname); - pacman_logaction(_("warning: %s saved as %s"), expath, newpath); - } - } - } else if(md5_orig || sha1_orig) { - /* PM_UPGRADE */ - int installnew = 0; - - /* the fun part */ - if(!strcmp(md5_orig, md5_local)|| !strcmp(sha1_orig, sha1_local)) { - if(!strcmp(md5_local, md5_pkg) || !strcmp(sha1_local, sha1_pkg)) { - _pacman_log(PM_LOG_DEBUG, _("action: installing new file")); - installnew = 1; - } else { - _pacman_log(PM_LOG_DEBUG, _("action: installing new file")); - installnew = 1; - } - } else if(!strcmp(md5_orig, md5_pkg) || !strcmp(sha1_orig, sha1_pkg)) { - _pacman_log(PM_LOG_DEBUG, _("action: leaving existing file in place")); - } else if(!strcmp(md5_local, md5_pkg) || !strcmp(sha1_local, sha1_pkg)) { - _pacman_log(PM_LOG_DEBUG, _("action: installing new file")); - installnew = 1; - } else { - char newpath[PATH_MAX]; - _pacman_log(PM_LOG_DEBUG, _("action: keeping current file and installing new one with .pacnew ending")); - installnew = 0; - snprintf(newpath, PATH_MAX, "%s.pacnew", expath); - if(_pacman_copyfile(temp, newpath)) { - _pacman_log(PM_LOG_ERROR, _("could not install %s as %s: %s"), expath, newpath, strerror(errno)); - pacman_logaction(_("error: could not install %s as %s: %s"), expath, newpath, strerror(errno)); - } else { - _pacman_log(PM_LOG_WARNING, _("%s installed as %s"), expath, newpath); - pacman_logaction(_("warning: %s installed as %s"), expath, newpath); - } - } - - if(installnew) { - _pacman_log(PM_LOG_FLOW2, _("extracting %s"), pathname); - if(_pacman_copyfile(temp, expath)) { - _pacman_log(PM_LOG_ERROR, _("could not copy %s to %s (%s)"), temp, pathname, strerror(errno)); - errors++; - } - archive_entry_set_pathname (entry, expath); - } - } - - FREE(md5_local); - FREE(md5_pkg); - FREE(md5_orig); - FREE(sha1_local); - FREE(sha1_pkg); - FREE(sha1_orig); - unlink(temp); - FREE(temp); - close(fd); - } else { - if(!notouch) { - _pacman_log(PM_LOG_FLOW2, _("extracting %s"), pathname); - } else { - _pacman_log(PM_LOG_FLOW2, _("%s is in NoUpgrade -- skipping"), pathname); - strncat(expath, ".pacnew", PATH_MAX); - _pacman_log(PM_LOG_WARNING, _("extracting %s as %s.pacnew"), pathname, pathname); - pacman_logaction(_("warning: extracting %s%s as %s"), handle->root, pathname, expath); - /*tar_skip_regfile(tar);*/ - } - if(trans->flags & PM_TRANS_FLAG_FORCE) { - /* if FORCE was used, then unlink() each file (whether it's there - * or not) before extracting. this prevents the old "Text file busy" - * error that crops up if one tries to --force a glibc or pacman-g2 - * upgrade. - */ - unlink(expath); - } - archive_entry_set_pathname (entry, expath); - if(archive_read_extract (archive, entry, ARCHIVE_EXTRACT_FLAGS) != ARCHIVE_OK) { - _pacman_log(PM_LOG_ERROR, _("could not extract %s (%s)"), expath, strerror(errno)); - pacman_logaction(_("error: could not extract %s (%s)"), expath, strerror(errno)); - errors++; - } - /* calculate an md5 or sha1 hash if this is in info->backup */ - for(lp = info->backup; lp; lp = lp->next) { - char *fn, *md5, *sha1; - char path[PATH_MAX]; - char *file = lp->data; - - if(!file) continue; - if(!strcmp(file, pathname)) { - _pacman_log(PM_LOG_DEBUG, _("appending backup entry")); - snprintf(path, PATH_MAX, "%s%s", handle->root, file); - if (info->sha1sum != NULL && info->sha1sum != '\0') { - md5 = _pacman_MDFile(path); - /* 32 for the hash, 1 for the terminating NULL, and 1 for the tab delimiter */ - if((fn = (char *)malloc(strlen(file)+34)) == NULL) { - RET_ERR(PM_ERR_MEMORY, -1); - } - sprintf(fn, "%s\t%s", file, md5); - FREE(md5); - } else { - /* 41 for the hash, 1 for the terminating NULL, and 1 for the tab delimiter */ - sha1 = _pacman_SHAFile(path); - if((fn = (char *)malloc(strlen(file)+43)) == NULL) { - RET_ERR(PM_ERR_MEMORY, -1); - } - sprintf(fn, "%s\t%s", file, sha1); - FREE(sha1); - } - FREE(file); - lp->data = fn; - } - } - } - } - if(archive_ret == ARCHIVE_FATAL) { - errors++; - } - if(strlen(cwd)) { - chdir(cwd); - } - archive_read_finish (archive); - - if(errors) { - ret = 1; - _pacman_log(PM_LOG_WARNING, _("errors occurred while %s %s"), - (pmo_upgrade ? _("upgrading") : _("installing")), info->name); - pacman_logaction(_("errors occurred while %s %s"), - (pmo_upgrade ? _("upgrading") : _("installing")), info->name); - } else { - PROGRESS(trans, cb_state, what, 100, howmany, howmany - remain + 1); - } - } - - /* Add the package to the database */ - t = time(NULL); - - /* Update the requiredby field by scanning the whole database - * looking for packages depending on the package to add */ - for(lp = _pacman_db_get_pkgcache(db); lp; lp = lp->next) { - pmpkg_t *tmpp = lp->data; - pmlist_t *tmppm = NULL; - if(tmpp == NULL) { - continue; - } - for(tmppm = tmpp->depends; tmppm; tmppm = tmppm->next) { - pmdepend_t depend; - if(_pacman_splitdep(tmppm->data, &depend)) { - continue; - } - if(tmppm->data && (!strcmp(depend.name, info->name) || _pacman_strlist_find(info->provides, depend.name))) { - _pacman_log(PM_LOG_DEBUG, _("adding '%s' in requiredby field for '%s'"), tmpp->name, info->name); - info->requiredby = _pacman_list_add(info->requiredby, strdup(tmpp->name)); - } - } - } - - /* make an install date (in UTC) */ - STRNCPY(info->installdate, asctime(gmtime(&t)), sizeof(info->installdate)); - /* remove the extra line feed appended by asctime() */ - info->installdate[strlen(info->installdate)-1] = 0; - - _pacman_log(PM_LOG_FLOW1, _("updating database")); - _pacman_log(PM_LOG_FLOW2, _("adding database entry '%s'"), info->name); - if(_pacman_db_write(db, info, INFRQ_ALL)) { - _pacman_log(PM_LOG_ERROR, _("could not update database entry %s-%s"), - info->name, info->version); - pacman_logaction(NULL, _("error updating database for %s-%s!"), info->name, info->version); - RET_ERR(PM_ERR_DB_WRITE, -1); - } - if(_pacman_db_add_pkgincache(db, info) == -1) { - _pacman_log(PM_LOG_ERROR, _("could not add entry '%s' in cache"), info->name); - } - - /* update dependency packages' REQUIREDBY fields */ - if(info->depends) { - _pacman_log(PM_LOG_FLOW2, _("updating dependency packages 'requiredby' fields")); - } - for(lp = info->depends; lp; lp = lp->next) { - pmpkg_t *depinfo; - pmdepend_t depend; - if(_pacman_splitdep(lp->data, &depend)) { - continue; - } - depinfo = _pacman_db_get_pkgfromcache(db, depend.name); - if(depinfo == NULL) { - /* look for a provides package */ - pmlist_t *provides = _pacman_db_whatprovides(db, depend.name); - if(provides) { - /* TODO: should check _all_ packages listed in provides, not just - * the first one. - */ - /* use the first one */ - depinfo = _pacman_db_get_pkgfromcache(db, ((pmpkg_t *)provides->data)->name); - FREELISTPTR(provides); - } - if(depinfo == NULL) { - _pacman_log(PM_LOG_ERROR, _("could not find dependency '%s'"), depend.name); - /* wtf */ - continue; - } - } - _pacman_log(PM_LOG_DEBUG, _("adding '%s' in requiredby field for '%s'"), info->name, depinfo->name); - depinfo->requiredby = _pacman_list_add(_pacman_pkg_getinfo(depinfo, PM_PKG_REQUIREDBY), strdup(info->name)); - if(_pacman_db_write(db, depinfo, INFRQ_DEPENDS)) { - _pacman_log(PM_LOG_ERROR, _("could not update 'requiredby' database entry %s-%s"), - depinfo->name, depinfo->version); - } - } - - needdisp = 0; - EVENT(trans, PM_TRANS_EVT_EXTRACT_DONE, NULL, NULL); - FREE(what); - - /* run the post-install script if it exists */ - if(info->scriptlet && !(trans->flags & PM_TRANS_FLAG_NOSCRIPTLET)) { - /* must run ldconfig here because some scriptlets fail due to missing libs otherwise */ - _pacman_ldconfig(handle->root); - snprintf(pm_install, PATH_MAX, "%s%s/%s/%s-%s/install", handle->root, handle->dbpath, db->treename, info->name, info->version); - if(pmo_upgrade) { - _pacman_runscriptlet(handle->root, pm_install, "post_upgrade", info->version, oldpkg ? oldpkg->version : NULL, trans); - } else { - _pacman_runscriptlet(handle->root, pm_install, "post_install", info->version, NULL, trans); - } - } - - EVENT(trans, (pmo_upgrade) ? PM_TRANS_EVT_UPGRADE_DONE : PM_TRANS_EVT_ADD_DONE, info, oldpkg); - - FREEPKG(oldpkg); - } - - /* run ldconfig if it exists */ - if(handle->trans->state != STATE_INTERRUPTED) { - _pacman_ldconfig(handle->root); - } - - return(ret); -} - -const pmtrans_ops_t _pacman_add_pmtrans_opts = { - .commit = _pacman_add_commit -}; - -/* vim: set ts=2 sw=2 noet: */ diff --git a/lib/libpacman/add.h b/lib/libpacman/add.h deleted file mode 100644 index 416f465..0000000 --- a/lib/libpacman/add.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * add.h - * - * Copyright (c) 2002-2006 by Judd Vinet <[email protected]> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - * USA. - */ -#ifndef _PACMAN_ADD_H -#define _PACMAN_ADD_H - -#include "trans.h" - -const pmtrans_ops_t _pacman_add_pmtrans_opts; - -#endif /* _PACMAN_ADD_H */ - -/* vim: set ts=2 sw=2 noet: */ diff --git a/lib/libpacman/pacman.c b/lib/libpacman/pacman.c index 6a8fdd9..c2fabaa 100644 --- a/lib/libpacman/pacman.c +++ b/lib/libpacman/pacman.c @@ -53,7 +53,6 @@ #include "cache.h" #include "conflict.h" #include "backup.h" -#include "add.h" #include "remove.h" #include "sync.h" #include "handle.h" diff --git a/lib/libpacman/trans.c b/lib/libpacman/trans.c index f012138..4e6c2e5 100644 --- a/lib/libpacman/trans.c +++ b/lib/libpacman/trans.c @@ -24,6 +24,7 @@ #include "config.h" +#include <errno.h> #include <stdlib.h> #include <stdio.h> #include <string.h> @@ -37,7 +38,6 @@ #include "util.h" #include "log.h" #include "handle.h" -#include "add.h" #include "remove.h" #include "sync.h" #include "cache.h" @@ -147,7 +147,7 @@ int _pacman_trans_init(pmtrans_t *trans, pmtranstype_t type, unsigned int flags, switch(type) { case PM_TRANS_TYPE_ADD: case PM_TRANS_TYPE_UPGRADE: - trans->ops = &_pacman_add_pmtrans_opts; + trans->ops = NULL; break; case PM_TRANS_TYPE_REMOVE: trans->ops = &_pacman_remove_pmtrans_opts; @@ -238,7 +238,6 @@ int _pacman_trans_addtarget(pmtrans_t *trans, const char *target, pmtranstype_t /* Sanity checks */ ASSERT(trans != NULL, RET_ERR(PM_ERR_TRANS_NULL, -1)); - ASSERT(trans->ops != NULL, RET_ERR(PM_ERR_TRANS_NULL, -1)); ASSERT(target != NULL && strlen(target) != 0, RET_ERR(PM_ERR_WRONG_ARGS, -1)); ASSERT(trans_pkg != NULL, return -1); /* pm_errno is allready set by __pacman_trans_pkg_new */ @@ -252,7 +251,7 @@ int _pacman_trans_addtarget(pmtrans_t *trans, const char *target, pmtranstype_t RET_ERR(PM_ERR_TRANS_DUP_TARGET, -1); } - if(trans->ops->addtarget != NULL) { + if(trans->ops != NULL && trans->ops->addtarget != NULL) { if (trans->ops->addtarget(trans, target) == -1) { /* pm_errno is set by trans->ops->addtarget() */ return(-1); @@ -405,7 +404,6 @@ int _pacman_trans_prepare(pmtrans_t *trans, pmlist_t **data) /* Sanity checks */ ASSERT(trans != NULL, RET_ERR(PM_ERR_TRANS_NULL, -1)); - ASSERT(trans->ops != NULL, RET_ERR(PM_ERR_TRANS_NULL, -1)); ASSERT(data != NULL, RET_ERR(PM_ERR_WRONG_ARGS, -1)); *data = NULL; @@ -418,7 +416,7 @@ int _pacman_trans_prepare(pmtrans_t *trans, pmlist_t **data) return(0); } - if(trans->ops->prepare != NULL) { + if(trans->ops != NULL && trans->ops->prepare != NULL) { if(trans->ops->prepare(trans, data) == -1) { /* pm_errno is set by trans->ops->prepare() */ return(-1); @@ -568,14 +566,19 @@ int _pacman_trans_prepare(pmtrans_t *trans, pmlist_t **data) int _pacman_trans_commit(pmtrans_t *trans, pmlist_t **data) { + pmdb_t *db_local; + int ret = 0; + /* Sanity checks */ ASSERT(trans != NULL, RET_ERR(PM_ERR_TRANS_NULL, -1)); - ASSERT(trans->ops != NULL, RET_ERR(PM_ERR_TRANS_NULL, -1)); - ASSERT(trans->ops->commit != NULL, RET_ERR(PM_ERR_TRANS_NULL, -1)); if(data!=NULL) *data = NULL; + db_local = trans->handle->db_local; + + ASSERT(db_local != NULL, RET_ERR(PM_ERR_DB_NULL, -1)); + /* If there's nothing to do, return without complaining */ if(trans->_packages == NULL && trans->packages == NULL) { return(0); @@ -583,15 +586,545 @@ int _pacman_trans_commit(pmtrans_t *trans, pmlist_t **data) _pacman_trans_set_state(trans, STATE_COMMITING); - if(trans->ops->commit(trans, data) == -1) { - /* pm_errno is set by trans->ops->commit() */ - _pacman_trans_set_state(trans, STATE_PREPARED); - return(-1); + if (trans->ops != NULL && trans->ops->commit != NULL) { + if (trans->ops->commit(trans, data) == -1) { + /* pm_errno is set by trans->ops->commit() */ + _pacman_trans_set_state(trans, STATE_PREPARED); + return(-1); + } + } else { + int i, errors = 0, needdisp = 0; + int remain, howmany, archive_ret; + double percent; + register struct archive *archive; + struct archive_entry *entry; + char expath[PATH_MAX], cwd[PATH_MAX] = "", *what; + unsigned char cb_state; + time_t t; + pmlist_t *targ, *lp; + + for(targ = trans->_packages; targ; targ = targ->next) { + unsigned short pmo_upgrade; + char pm_install[PATH_MAX]; + pmpkg_t *info = (pmpkg_t *)targ->data; + pmpkg_t *oldpkg = NULL; + errors = 0; + remain = _pacman_list_count(targ); + howmany = _pacman_list_count(trans->_packages); + + if(handle->trans->state == STATE_INTERRUPTED) { + break; + } + + pmo_upgrade = (trans->type == PM_TRANS_TYPE_UPGRADE) ? 1 : 0; + + /* see if this is an upgrade. if so, remove the old package first */ + if(pmo_upgrade) { + pmpkg_t *local = _pacman_db_get_pkgfromcache(db_local, info->name); + if(local) { + EVENT(trans, PM_TRANS_EVT_UPGRADE_START, info, NULL); + cb_state = PM_TRANS_PROGRESS_UPGRADE_START; + _pacman_log(PM_LOG_FLOW1, _("upgrading package %s-%s"), info->name, info->version); + if((what = (char *)malloc(strlen(info->name)+1)) == NULL) { + RET_ERR(PM_ERR_MEMORY, -1); + } + STRNCPY(what, info->name, strlen(info->name)+1); + + /* we'll need to save some record for backup checks later */ + oldpkg = _pacman_pkg_new(local->name, local->version); + if(oldpkg) { + if(!(local->infolevel & INFRQ_FILES)) { + _pacman_log(PM_LOG_DEBUG, _("loading FILES info for '%s'"), local->name); + _pacman_db_read(db_local, INFRQ_FILES, local); + } + oldpkg->backup = _pacman_strlist_dup(local->backup); + strncpy(oldpkg->name, local->name, PKG_NAME_LEN); + strncpy(oldpkg->version, local->version, PKG_VERSION_LEN); + } + + /* pre_upgrade scriptlet */ + if(info->scriptlet && !(trans->flags & PM_TRANS_FLAG_NOSCRIPTLET)) { + _pacman_runscriptlet(handle->root, info->data, "pre_upgrade", info->version, oldpkg ? oldpkg->version : NULL, + trans); + } + + if(oldpkg) { + pmtrans_t *tr; + _pacman_log(PM_LOG_FLOW1, _("removing old package first (%s-%s)"), oldpkg->name, oldpkg->version); + tr = _pacman_trans_new(); + if(tr == NULL) { + RET_ERR(PM_ERR_TRANS_ABORT, -1); + } + pmtrans_cbs_t null_cbs = { NULL }; + if(_pacman_trans_init(tr, PM_TRANS_TYPE_UPGRADE, trans->flags, null_cbs) == -1) { + FREETRANS(tr); + RET_ERR(PM_ERR_TRANS_ABORT, -1); + } + if(_pacman_trans_addtarget(tr, info->name, PM_TRANS_TYPE_REMOVE, 0) == -1) { + FREETRANS(tr); + RET_ERR(PM_ERR_TRANS_ABORT, -1); + } + /* copy the skiplist over */ + tr->skiplist = _pacman_strlist_dup(trans->skiplist); + if(_pacman_remove_commit(tr, NULL) == -1) { + FREETRANS(tr); + RET_ERR(PM_ERR_TRANS_ABORT, -1); + } + FREETRANS(tr); + } + } else { + /* no previous package version is installed, so this is actually + * just an install. */ + pmo_upgrade = 0; + } + } + if(!pmo_upgrade) { + EVENT(trans, PM_TRANS_EVT_ADD_START, info, NULL); + cb_state = PM_TRANS_PROGRESS_ADD_START; + _pacman_log(PM_LOG_FLOW1, _("adding package %s-%s"), info->name, info->version); + if((what = (char *)malloc(strlen(info->name)+1)) == NULL) { + RET_ERR(PM_ERR_MEMORY, -1); + } + STRNCPY(what, info->name, strlen(info->name)+1); + + /* pre_install scriptlet */ + if(info->scriptlet && !(trans->flags & PM_TRANS_FLAG_NOSCRIPTLET)) { + _pacman_runscriptlet(handle->root, info->data, "pre_install", info->version, NULL, trans); + } + } else { + _pacman_log(PM_LOG_FLOW1, _("adding new package %s-%s"), info->name, info->version); + } + + if(!(trans->flags & PM_TRANS_FLAG_DBONLY)) { + _pacman_log(PM_LOG_FLOW1, _("extracting files")); + + /* Extract the package */ + if ((archive = archive_read_new ()) == NULL) + RET_ERR(PM_ERR_LIBARCHIVE_ERROR, -1); + + archive_read_support_compression_all (archive); + archive_read_support_format_all (archive); + + if (archive_read_open_file (archive, info->data, PM_DEFAULT_BYTES_PER_BLOCK) != ARCHIVE_OK) { + RET_ERR(PM_ERR_PKG_OPEN, -1); + } + + /* save the cwd so we can restore it later */ + if(getcwd(cwd, PATH_MAX) == NULL) { + _pacman_log(PM_LOG_ERROR, _("could not get current working directory")); + /* in case of error, cwd content is undefined: so we set it to something */ + cwd[0] = 0; + } + + /* libarchive requires this for extracting hard links */ + chdir(handle->root); + + for(i = 0; (archive_ret = archive_read_next_header (archive, &entry)) == ARCHIVE_OK; i++) { + int nb = 0; + int notouch = 0; + char *md5_orig = NULL; + char *sha1_orig = NULL; + char pathname[PATH_MAX]; + struct stat buf; + + STRNCPY(pathname, archive_entry_pathname (entry), PATH_MAX); + + if (info->size != 0) + percent = (double)archive_position_uncompressed(archive) / info->size; + if (needdisp == 0) { + PROGRESS(trans, cb_state, what, (int)(percent * 100), howmany, (howmany - remain +1)); + } + + if(!strcmp(pathname, ".PKGINFO") || !strcmp(pathname, ".FILELIST")) { + archive_read_data_skip (archive); + continue; + } + + /*if(!strcmp(pathname, "._install") || !strcmp(pathname, ".INSTALL")) { + * the install script goes inside the db + * snprintf(expath, PATH_MAX, "%s/%s-%s/install", db->path, info->name, info->version); */ + if(!strcmp(pathname, "._install") || !strcmp(pathname, ".INSTALL") || + !strcmp(pathname, ".CHANGELOG")) { + if(!strcmp(pathname, ".CHANGELOG")) { + /* the changelog goes inside the db */ + snprintf(expath, PATH_MAX, "%s/%s-%s/changelog", db_local->path, + info->name, info->version); + } else { + /* the install script goes inside the db */ + snprintf(expath, PATH_MAX, "%s/%s-%s/install", db_local->path, + info->name, info->version); + } + } else { + /* build the new pathname relative to handle->root */ + snprintf(expath, PATH_MAX, "%s%s", handle->root, pathname); + if(expath[strlen(expath)-1] == '/') { + expath[strlen(expath)-1] = '\0'; + } + } + + /* if a file is in NoExtract then we never extract it. + * + * eg, /home/httpd/html/index.html may be removed so index.php + * could be used. + */ + if(_pacman_strlist_find(handle->noextract, pathname)) { + pacman_logaction(_("notice: %s is in NoExtract -- skipping extraction"), pathname); + archive_read_data_skip (archive); + continue; + } + + if(!lstat(expath, &buf)) { + /* file already exists */ + if(S_ISLNK(buf.st_mode)) { + continue; + } else if(!S_ISDIR(buf.st_mode)) { + if(_pacman_strlist_find(handle->noupgrade, pathname)) { + notouch = 1; + } else { + if(!pmo_upgrade || oldpkg == NULL) { + nb = _pacman_strlist_find(info->backup, pathname); + } else { + /* op == PM_TRANS_TYPE_UPGRADE */ + md5_orig = _pacman_needbackup(pathname, oldpkg->backup); + sha1_orig = _pacman_needbackup(pathname, oldpkg->backup); + if(md5_orig || sha1_orig) { + nb = 1; + } + } + } + } + } + + if(nb) { + char *temp; + char *md5_local, *md5_pkg; + char *sha1_local, *sha1_pkg; + int fd; + + /* extract the package's version to a temporary file and md5 it */ + temp = strdup("/tmp/pacman_XXXXXX"); + fd = mkstemp(temp); + + archive_entry_set_pathname (entry, temp); + + if(archive_read_extract (archive, entry, ARCHIVE_EXTRACT_FLAGS) != ARCHIVE_OK) { + _pacman_log(PM_LOG_ERROR, _("could not extract %s (%s)"), pathname, strerror(errno)); + pacman_logaction(_("could not extract %s (%s)"), pathname, strerror(errno)); + errors++; + unlink(temp); + FREE(temp); + FREE(md5_orig); + FREE(sha1_orig); + close(fd); + continue; + } + md5_local = _pacman_MDFile(expath); + md5_pkg = _pacman_MDFile(temp); + sha1_local = _pacman_SHAFile(expath); + sha1_pkg = _pacman_SHAFile(temp); + /* append the new md5 or sha1 hash to it's respective entry in info->backup + * (it will be the new orginal) + */ + for(lp = info->backup; lp; lp = lp->next) { + char *fn; + char *file = lp->data; + + if(!file) continue; + if(!strcmp(file, pathname)) { + if(info->sha1sum != NULL && info->sha1sum != '\0') { + /* 32 for the hash, 1 for the terminating NULL, and 1 for the tab delimiter */ + if((fn = (char *)malloc(strlen(file)+34)) == NULL) { + RET_ERR(PM_ERR_MEMORY, -1); + } + sprintf(fn, "%s\t%s", file, md5_pkg); + FREE(file); + lp->data = fn; + } else { + /* 41 for the hash, 1 for the terminating NULL, and 1 for the tab delimiter */ + if((fn = (char *)malloc(strlen(file)+43)) == NULL) { + RET_ERR(PM_ERR_MEMORY, -1); + } + sprintf(fn, "%s\t%s", file, sha1_pkg); + FREE(file); + lp->data = fn; + } + } + } + + if (info->sha1sum != NULL && info->sha1sum != '\0') { + _pacman_log(PM_LOG_DEBUG, _("checking md5 hashes for %s"), pathname); + _pacman_log(PM_LOG_DEBUG, _("current: %s"), md5_local); + _pacman_log(PM_LOG_DEBUG, _("new: %s"), md5_pkg); + if(md5_orig) { + _pacman_log(PM_LOG_DEBUG, _("original: %s"), md5_orig); + } + } else { + _pacman_log(PM_LOG_DEBUG, _("checking sha1 hashes for %s"), pathname); + _pacman_log(PM_LOG_DEBUG, _("current: %s"), sha1_local); + _pacman_log(PM_LOG_DEBUG, _("new: %s"), sha1_pkg); + if(sha1_orig) { + _pacman_log(PM_LOG_DEBUG, _("original: %s"), sha1_orig); + } + } + + if(!pmo_upgrade) { + /* PM_ADD */ + + /* if a file already exists with a different md5 or sha1 hash, + * then we rename it to a .pacorig extension and continue */ + if(strcmp(md5_local, md5_pkg) || strcmp(sha1_local, sha1_pkg)) { + char newpath[PATH_MAX]; + snprintf(newpath, PATH_MAX, "%s.pacorig", expath); + if(rename(expath, newpath)) { + archive_entry_set_pathname (entry, expath); + _pacman_log(PM_LOG_ERROR, _("could not rename %s (%s)"), pathname, strerror(errno)); + pacman_logaction(_("error: could not rename %s (%s)"), expath, strerror(errno)); + } + if(_pacman_copyfile(temp, expath)) { + archive_entry_set_pathname (entry, expath); + _pacman_log(PM_LOG_ERROR, _("could not copy %s to %s (%s)"), temp, pathname, strerror(errno)); + pacman_logaction(_("error: could not copy %s to %s (%s)"), temp, expath, strerror(errno)); + errors++; + } else { + archive_entry_set_pathname (entry, expath); + _pacman_log(PM_LOG_WARNING, _("%s saved as %s.pacorig"), pathname, pathname); + pacman_logaction(_("warning: %s saved as %s"), expath, newpath); + } + } + } else if(md5_orig || sha1_orig) { + /* PM_UPGRADE */ + int installnew = 0; + + /* the fun part */ + if(!strcmp(md5_orig, md5_local)|| !strcmp(sha1_orig, sha1_local)) { + if(!strcmp(md5_local, md5_pkg) || !strcmp(sha1_local, sha1_pkg)) { + _pacman_log(PM_LOG_DEBUG, _("action: installing new file")); + installnew = 1; + } else { + _pacman_log(PM_LOG_DEBUG, _("action: installing new file")); + installnew = 1; + } + } else if(!strcmp(md5_orig, md5_pkg) || !strcmp(sha1_orig, sha1_pkg)) { + _pacman_log(PM_LOG_DEBUG, _("action: leaving existing file in place")); + } else if(!strcmp(md5_local, md5_pkg) || !strcmp(sha1_local, sha1_pkg)) { + _pacman_log(PM_LOG_DEBUG, _("action: installing new file")); + installnew = 1; + } else { + char newpath[PATH_MAX]; + _pacman_log(PM_LOG_DEBUG, _("action: keeping current file and installing new one with .pacnew ending")); + installnew = 0; + snprintf(newpath, PATH_MAX, "%s.pacnew", expath); + if(_pacman_copyfile(temp, newpath)) { + _pacman_log(PM_LOG_ERROR, _("could not install %s as %s: %s"), expath, newpath, strerror(errno)); + pacman_logaction(_("error: could not install %s as %s: %s"), expath, newpath, strerror(errno)); + } else { + _pacman_log(PM_LOG_WARNING, _("%s installed as %s"), expath, newpath); + pacman_logaction(_("warning: %s installed as %s"), expath, newpath); + } + } + + if(installnew) { + _pacman_log(PM_LOG_FLOW2, _("extracting %s"), pathname); + if(_pacman_copyfile(temp, expath)) { + _pacman_log(PM_LOG_ERROR, _("could not copy %s to %s (%s)"), temp, pathname, strerror(errno)); + errors++; + } + archive_entry_set_pathname (entry, expath); + } + } + + FREE(md5_local); + FREE(md5_pkg); + FREE(md5_orig); + FREE(sha1_local); + FREE(sha1_pkg); + FREE(sha1_orig); + unlink(temp); + FREE(temp); + close(fd); + } else { + if(!notouch) { + _pacman_log(PM_LOG_FLOW2, _("extracting %s"), pathname); + } else { + _pacman_log(PM_LOG_FLOW2, _("%s is in NoUpgrade -- skipping"), pathname); + strncat(expath, ".pacnew", PATH_MAX); + _pacman_log(PM_LOG_WARNING, _("extracting %s as %s.pacnew"), pathname, pathname); + pacman_logaction(_("warning: extracting %s%s as %s"), handle->root, pathname, expath); + /*tar_skip_regfile(tar);*/ + } + if(trans->flags & PM_TRANS_FLAG_FORCE) { + /* if FORCE was used, then unlink() each file (whether it's there + * or not) before extracting. this prevents the old "Text file busy" + * error that crops up if one tries to --force a glibc or pacman-g2 + * upgrade. + */ + unlink(expath); + } + archive_entry_set_pathname (entry, expath); + if(archive_read_extract (archive, entry, ARCHIVE_EXTRACT_FLAGS) != ARCHIVE_OK) { + _pacman_log(PM_LOG_ERROR, _("could not extract %s (%s)"), expath, strerror(errno)); + pacman_logaction(_("error: could not extract %s (%s)"), expath, strerror(errno)); + errors++; + } + /* calculate an md5 or sha1 hash if this is in info->backup */ + for(lp = info->backup; lp; lp = lp->next) { + char *fn, *md5, *sha1; + char path[PATH_MAX]; + char *file = lp->data; + + if(!file) continue; + if(!strcmp(file, pathname)) { + _pacman_log(PM_LOG_DEBUG, _("appending backup entry")); + snprintf(path, PATH_MAX, "%s%s", handle->root, file); + if (info->sha1sum != NULL && info->sha1sum != '\0') { + md5 = _pacman_MDFile(path); + /* 32 for the hash, 1 for the terminating NULL, and 1 for the tab delimiter */ + if((fn = (char *)malloc(strlen(file)+34)) == NULL) { + RET_ERR(PM_ERR_MEMORY, -1); + } + sprintf(fn, "%s\t%s", file, md5); + FREE(md5); + } else { + /* 41 for the hash, 1 for the terminating NULL, and 1 for the tab delimiter */ + sha1 = _pacman_SHAFile(path); + if((fn = (char *)malloc(strlen(file)+43)) == NULL) { + RET_ERR(PM_ERR_MEMORY, -1); + } + sprintf(fn, "%s\t%s", file, sha1); + FREE(sha1); + } + FREE(file); + lp->data = fn; + } + } + } + } + if(archive_ret == ARCHIVE_FATAL) { + errors++; + } + if(strlen(cwd)) { + chdir(cwd); + } + archive_read_finish (archive); + + if(errors) { + ret = 1; + _pacman_log(PM_LOG_WARNING, _("errors occurred while %s %s"), + (pmo_upgrade ? _("upgrading") : _("installing")), info->name); + pacman_logaction(_("errors occurred while %s %s"), + (pmo_upgrade ? _("upgrading") : _("installing")), info->name); + } else { + PROGRESS(trans, cb_state, what, 100, howmany, howmany - remain + 1); + } + } + + /* Add the package to the database */ + t = time(NULL); + + /* Update the requiredby field by scanning the whole database + * looking for packages depending on the package to add */ + for(lp = _pacman_db_get_pkgcache(db_local); lp; lp = lp->next) { + pmpkg_t *tmpp = lp->data; + pmlist_t *tmppm = NULL; + if(tmpp == NULL) { + continue; + } + for(tmppm = tmpp->depends; tmppm; tmppm = tmppm->next) { + pmdepend_t depend; + if(_pacman_splitdep(tmppm->data, &depend)) { + continue; + } + if(tmppm->data && (!strcmp(depend.name, info->name) || _pacman_strlist_find(info->provides, depend.name))) { + _pacman_log(PM_LOG_DEBUG, _("adding '%s' in requiredby field for '%s'"), tmpp->name, info->name); + info->requiredby = _pacman_list_add(info->requiredby, strdup(tmpp->name)); + } + } + } + + /* make an install date (in UTC) */ + STRNCPY(info->installdate, asctime(gmtime(&t)), sizeof(info->installdate)); + /* remove the extra line feed appended by asctime() */ + info->installdate[strlen(info->installdate)-1] = 0; + + _pacman_log(PM_LOG_FLOW1, _("updating database")); + _pacman_log(PM_LOG_FLOW2, _("adding database entry '%s'"), info->name); + if(_pacman_db_write(db_local, info, INFRQ_ALL)) { + _pacman_log(PM_LOG_ERROR, _("could not update database entry %s-%s"), + info->name, info->version); + pacman_logaction(NULL, _("error updating database for %s-%s!"), info->name, info->version); + RET_ERR(PM_ERR_DB_WRITE, -1); + } + if(_pacman_db_add_pkgincache(db_local, info) == -1) { + _pacman_log(PM_LOG_ERROR, _("could not add entry '%s' in cache"), info->name); + } + + /* update dependency packages' REQUIREDBY fields */ + if(info->depends) { + _pacman_log(PM_LOG_FLOW2, _("updating dependency packages 'requiredby' fields")); + } + for(lp = info->depends; lp; lp = lp->next) { + pmpkg_t *depinfo; + pmdepend_t depend; + if(_pacman_splitdep(lp->data, &depend)) { + continue; + } + depinfo = _pacman_db_get_pkgfromcache(db_local, depend.name); + if(depinfo == NULL) { + /* look for a provides package */ + pmlist_t *provides = _pacman_db_whatprovides(db_local, depend.name); + if(provides) { + /* TODO: should check _all_ packages listed in provides, not just + * the first one. + */ + /* use the first one */ + depinfo = _pacman_db_get_pkgfromcache(db_local, ((pmpkg_t *)provides->data)->name); + FREELISTPTR(provides); + } + if(depinfo == NULL) { + _pacman_log(PM_LOG_ERROR, _("could not find dependency '%s'"), depend.name); + /* wtf */ + continue; + } + } + _pacman_log(PM_LOG_DEBUG, _("adding '%s' in requiredby field for '%s'"), info->name, depinfo->name); + depinfo->requiredby = _pacman_list_add(_pacman_pkg_getinfo(depinfo, PM_PKG_REQUIREDBY), strdup(info->name)); + if(_pacman_db_write(db_local, depinfo, INFRQ_DEPENDS)) { + _pacman_log(PM_LOG_ERROR, _("could not update 'requiredby' database entry %s-%s"), + depinfo->name, depinfo->version); + } + } + + needdisp = 0; + EVENT(trans, PM_TRANS_EVT_EXTRACT_DONE, NULL, NULL); + FREE(what); + + /* run the post-install script if it exists */ + if(info->scriptlet && !(trans->flags & PM_TRANS_FLAG_NOSCRIPTLET)) { + /* must run ldconfig here because some scriptlets fail due to missing libs otherwise */ + _pacman_ldconfig(handle->root); + snprintf(pm_install, PATH_MAX, "%s%s/%s/%s-%s/install", handle->root, handle->dbpath, db_local->treename, info->name, info->version); + if(pmo_upgrade) { + _pacman_runscriptlet(handle->root, pm_install, "post_upgrade", info->version, oldpkg ? oldpkg->version : NULL, trans); + } else { + _pacman_runscriptlet(handle->root, pm_install, "post_install", info->version, NULL, trans); + } + } + + EVENT(trans, (pmo_upgrade) ? PM_TRANS_EVT_UPGRADE_DONE : PM_TRANS_EVT_ADD_DONE, info, oldpkg); + + FREEPKG(oldpkg); + } + + /* run ldconfig if it exists */ + if(handle->trans->state != STATE_INTERRUPTED) { + _pacman_ldconfig(handle->root); + } + } _pacman_trans_set_state(trans, STATE_COMMITED); - return(0); + return(ret); } /* vim: set ts=2 sw=2 noet: */ _______________________________________________ Frugalware-git mailing list [email protected] http://frugalware.org/mailman/listinfo/frugalware-git
