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

Reply via email to