Imported from pacman-2.9.6.tar.gz

This commit is contained in:
Judd Vinet 2005-06-10 21:31:25 +00:00
parent d48cc3bf5d
commit d05f0047a0
18 changed files with 489 additions and 254 deletions

View file

@ -1,5 +1,16 @@
VERSION DESCRIPTION
-----------------------------------------------------------------------------
2.9.6 - added a pacman-optimize script to try and defragment the DB
- modified NoUpgrade behaviour to avoid extracting files
that are missing from the filesystem -- this helps in
situations where the admin does not want the file there, eg,
remove index.html so index.php takes precedence
- fixed a bug where files would sometimes go missing if they
moved from one package to another
- add db_remove() which is responsible for clearing out stale
hash table entries when packages are removed
- added cache support to makepkg
- patch from Aurelien Foret fixes a few memory leaks
2.9.5 - bugfix: missing files after re-ordering packages wrt
deps with --upgrade
- added "Repository" line to -Si output

View file

@ -34,7 +34,7 @@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
INSTALL_DATA = @INSTALL_DATA@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
PACVER = 2.9.5
PACVER = 2.9.6
TOPDIR = @srcdir@
SRCDIR = $(TOPDIR)/src/
@ -106,6 +106,7 @@ install: pacman vercmp convertdb man
$(INSTALL) -D -m0755 $(SCRDIR)makeworld $(DESTDIR)$(BINDIR)/makeworld
$(INSTALL) -D -m0755 $(SCRDIR)gensync $(DESTDIR)$(BINDIR)/gensync
$(INSTALL) -D -m0755 $(SCRDIR)updatesync $(DESTDIR)$(BINDIR)/updatesync
$(INSTALL) -D -m0755 $(SCRDIR)pacman-optimize $(DESTDIR)$(BINDIR)/pacman-optimize
$(INSTALL) -D -m0644 $(MANSRC)pacman.8 $(DESTDIR)$(MANDIR)/man8/pacman.8
$(INSTALL) -D -m0644 $(MANSRC)makepkg.8 $(DESTDIR)$(MANDIR)/man8/makepkg.8
$(INSTALL) -D -m0644 etc/pacman.conf $(DESTDIR)/etc/pacman.conf

View file

@ -81,7 +81,7 @@ Output more status and error messages.
Specify an alternate configuration file.
.TP
.B "\-\-noconfirm"
Bypass any and all "Are you sure?" messages. It's not a good to do this
Bypass any and all "Are you sure?" messages. It's not a good idea to do this
unless you want to run pacman from a script.
.SH SYNC OPTIONS
.TP

View file

@ -12,8 +12,8 @@ export CHOST="i686-pc-linux-gnu"
# Pentium Pro/Pentium II/Pentium III+/Pentium 4/Athlon exclusive (binaries
# will use the P6 instruction set and only run on P6+ systems)
export CFLAGS="-march=i686 -O2 -pipe"
export CXXFLAGS="-march=i686 -O2 -pipe"
export CFLAGS="-march=i686 -O2 -pipe -Wl,-O1"
export CXXFLAGS="-march=i686 -O2 -pipe -Wl,-O1"
# Pentium Pro/Pentium II/Pentium III+/Pentium 4/Athlon optimized (but binaries
# will run on any x86 system)
#export CFLAGS="-mcpu=i686 -O2 -pipe"
@ -26,7 +26,7 @@ export CXXFLAGS="-march=i686 -O2 -pipe"
export USE_FAKEROOT="y"
# Enable colorized output messages
export USE_COLOR="n"
export USE_COLOR="y"
# Specify a fixed directory where all packages will be placed
#export PKGDEST=/home/packages

View file

@ -2,7 +2,7 @@
#
# gensync
#
# Copyright (c) 2002-2004 by Judd Vinet <jvinet@zeroflux.org>
# Copyright (c) 2002-2005 by Judd Vinet <jvinet@zeroflux.org>
#
# 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
@ -20,7 +20,7 @@
# USA.
#
myver='2.9.2'
myver='2.9.6'
usage() {
echo "gensync $myver"

View file

@ -2,7 +2,7 @@
#
# makepkg
#
# Copyright (c) 2002-2004 by Judd Vinet <jvinet@zeroflux.org>
# Copyright (c) 2002-2005 by Judd Vinet <jvinet@zeroflux.org>
#
# 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
@ -20,7 +20,7 @@
# USA.
#
myver='2.9.2'
myver='2.9.6'
startdir=`pwd`
PKGDEST=$startdir
USE_COLOR="n"
@ -357,7 +357,7 @@ if [ "`id -u`" != "0" ]; then
fi
fi
msg "Making package: $pkgname (`date`)"
msg "Making package: $pkgname $pkgver-$pkgrel (`date`)"
unset deplist makedeplist
if [ `type -p pacman` -a "$NODEPS" = "0" ]; then
@ -552,6 +552,9 @@ if [ "$NOBUILD" = "1" ]; then
exit 0
fi
# use ccache if it's available
[ -d /usr/lib/ccache/bin ] && export PATH=/usr/lib/ccache/bin:$PATH
# build
msg "Starting build()..."
build 2>&1

View file

@ -2,7 +2,7 @@
#
# makeworld
#
# Copyright (c) 2002-2004 by Judd Vinet <jvinet@zeroflux.org>
# Copyright (c) 2002-2005 by Judd Vinet <jvinet@zeroflux.org>
#
# 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
@ -20,8 +20,8 @@
# USA.
#
version="2.9.6"
toplevel=`pwd`
version="2.9.2"
usage() {
echo "makeworld version $version"
@ -106,12 +106,12 @@ fi
# convert a (possibly) relative path to absolute
cd $dest
dest=`pwd`
cd -
cd - &>/dev/null
sd=`date +"[%b %d %H:%M]"`
for category in $*; do
for port in `find $toplevel/$category -type d -maxdepth 1 -mindepth 1 | sort`; do
for port in `find $toplevel/$category -maxdepth 1 -mindepth 1 -type d | sort`; do
cd $port
if [ -f PKGBUILD ]; then
. PKGBUILD

114
scripts/pacman-optimize Executable file
View file

@ -0,0 +1,114 @@
#!/bin/bash
#
# pacman-optimize
#
# Copyright (c) 2002-2005 by Judd Vinet <jvinet@zeroflux.org>
#
# 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.
#
myver='2.9.6'
usage() {
echo "pacman-optimize $myver"
echo "usage: $0 [pacman_db_root]"
echo
echo "pacman-optimize is a little hack that should improve the performance"
echo "of pacman when reading/writing to its filesystem-based database."
echo
echo "Because pacman uses many small files to keep track of packages,"
echo "there is a tendency for these files to become fragmented over time."
echo "This script attempts to relocate these small files into one"
echo "contiguous location on your hard drive. The result is that the hard"
echo "drive should be able to read them faster, since the hard drive head"
echo "does not have to move around the disk as much."
echo
}
die() {
echo "pacman-optimize: $*" >&2
exit 1
}
die_r() {
rm -f /tmp/pacman.lck
die $*
}
dbroot="/var/lib/pacman"
if [ "$1" != "" ]; then
if [ "$1" = "-h" -o "$1" = "--help" ]; then
usage
exit 0
fi
dbroot=$1
fi
if [ "`id -u`" != 0 ]; then
die "You must be root to optimize the database"
fi
# make sure pacman isn't running
if [ -f /tmp/pacman.lck ]; then
die "Pacman lockfile was found. Cannot run while pacman is running."
fi
if [ ! -d $dbroot ]; then
die "$dbroot does not exist or is not a directory"
fi
# don't let pacman run while we do this
touch /tmp/pacman.lck
# step 1: sum the old db
echo "==> md5sum'ing the old database..."
tar c $dbroot 2>/dev/null | md5sum >/tmp/pacsums.old
# step 1: copy the entire db directory to a new one
echo "==> copying $dbroot..."
cp -a $dbroot $dbroot.new || die_r "error copying $dbroot"
# step 2: switch the directory names and sum the new one
echo "==> md5sum'ing the new database..."
mv $dbroot $dbroot.bak || die_r "error renaming $dbroot"
mv $dbroot.new $dbroot || die_r "error renaming $dbroot.new"
tar c $dbroot 2>/dev/null | md5sum >/tmp/pacsums.new
# step 3: compare sums
echo "==> checking integrity..."
diff /tmp/pacsums.old /tmp/pacsums.new >/dev/null 2>&1
if [ $? -ne 0 ]; then
# failed, move the old one back into place
rm -rf $dbroot
mv $dbroot.bak $dbroot
die_r "integrity check FAILED, reverting to old databse"
fi
# step 4: remove the backup
echo "==> removing old database..."
rm -rf $dbroot.bak || die_r "error removing backup $dbroot.bak"
# remove the lock and sum files
rm -f /tmp/pacman.lck /tmp/pacsums.old /tmp/pacsums.new
echo
echo "Finished. Your pacman database has been optimized."
echo
exit 0

View file

@ -3,7 +3,7 @@
# updatesync
#
# Copyright (c) 2004 by Jason Chu <jason@archlinux.org>
# Derived from gensync (c) 2002-2004 Judd Vinet <jvinet@zeroflux.org>
# Derived from gensync (c) 2002-2005 Judd Vinet <jvinet@zeroflux.org>
#
# 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
@ -21,7 +21,7 @@
# USA.
#
myver='2.9.2'
myver='2.9.6'
usage() {
echo "updatesync $myver"

125
src/db.c
View file

@ -137,21 +137,32 @@ pkginfo_t* db_scan(pacdb_t *db, char *target, unsigned int inforeq)
char *ptr = NULL;
int found = 0;
/* hash table for caching directory names */
static strhash_t* htable = NULL;
if (!htable)
htable = new_strhash(951);
/* initialize the hash table */
if(!db_htable) {
db_htable = new_strhash(951);
}
snprintf(path, PATH_MAX, "%s/", db->path);
path_len = strlen(path);
/* TODO:
*
* Currently we're using a hash table to cache the directory
* name of each package we db_scan() for. This saves us from
* having to scan the db directory for the full
* pkgname-pkgver-pkgrel dir name, but we still have to issue
* a db_read() call to get the actual package data.
*
* A more efficient method may be to cache the package data
* itself.
*/
if(target != NULL) {
/* search for a specific package (by name only) */
/* See if we have the path cached. */
strcat(path, target);
if (strhash_isin(htable, path)) {
if(strhash_isin(db_htable, path)) {
struct dirent* pkgdir;
pkginfo_t* pkg;
@ -159,7 +170,7 @@ pkginfo_t* db_scan(pacdb_t *db, char *target, unsigned int inforeq)
* Actually it only uses the d_name field. */
MALLOC(pkgdir, sizeof(struct dirent));
strcpy(pkgdir->d_name, strhash_get(htable, path));
strcpy(pkgdir->d_name, strhash_get(db_htable, path));
pkg = db_read(db, pkgdir, inforeq);
FREE(pkgdir);
@ -242,8 +253,8 @@ pkginfo_t* db_scan(pacdb_t *db, char *target, unsigned int inforeq)
* data: xrally-1.1.1-1
*/
if (!strhash_isin(htable, path)) {
strhash_add(htable, strdup(path), strdup(ent->d_name));
if(!strhash_isin(db_htable, path)) {
strhash_add(db_htable, strdup(path), strdup(ent->d_name));
}
}
}
@ -595,6 +606,40 @@ int db_write(pacdb_t *db, pkginfo_t *info, unsigned int inforeq)
return(0);
}
/*
* Remove a package record from the database
*/
void db_remove(pacdb_t *db, pkginfo_t *target)
{
char topdir[PATH_MAX];
char path[PATH_MAX];
snprintf(topdir, PATH_MAX, "%s/%s-%s", db->path,
target->name, target->version);
/* DESC */
snprintf(path, PATH_MAX, "%s/desc", topdir);
unlink(path);
/* FILES */
snprintf(path, PATH_MAX, "%s/files", topdir);
unlink(path);
/* DEPENDS */
snprintf(path, PATH_MAX, "%s/depends", topdir);
unlink(path);
/* INSTALL */
snprintf(path, PATH_MAX, "%s/install", topdir);
unlink(path);
/* directory */
rmdir(topdir);
/* remove the entry from the hash table */
if(db_htable) {
/*clear_strhash(db_htable);*/
snprintf(topdir, PATH_MAX, "%s/%s", db->path, target->name);
strhash_remove(db_htable, topdir);
}
}
void db_search(pacdb_t *db, PMList *cache, const char *treename, PMList *needles)
{
PMList *i, *j;
@ -655,7 +700,7 @@ void db_search(pacdb_t *db, PMList *cache, const char *treename, PMList *needles
}
PMList* db_find_conflicts(pacdb_t *db, PMList *targets, char *root)
PMList* db_find_conflicts(pacdb_t *db, PMList *targets, char *root, PMList **skip_list)
{
PMList *i, *j, *k;
char *filestr = NULL;
@ -663,6 +708,7 @@ PMList* db_find_conflicts(pacdb_t *db, PMList *targets, char *root)
char *str = NULL;
struct stat buf, buf2;
PMList *conflicts = NULL;
strhash_t** htables;
int target_num = 0;
int d = 0;
@ -680,42 +726,12 @@ PMList* db_find_conflicts(pacdb_t *db, PMList *targets, char *root)
for(d = 0, i = targets; i; i = i->next, d++) {
htables[d] = new_strhash(151);
strhash_add_list(htables[d], ((pkginfo_t*)i->data)->files);
}
htables[target_num] = new_strhash(151);
/* CHECK 1: check every db package against every target package */
/* XXX: I've disabled the database-against-targets check for now, as the
* many many strcmp() calls slow it down heavily and most of the
* checking is redundant to the targets-against-filesystem check.
* This will be re-enabled if I can improve performance significantly.
*
pkginfo_t *info = NULL;
char *dbstr = NULL;
rewinddir(db->dir);
while((info = db_scan(db, NULL, INFRQ_DESC | INFRQ_FILES)) != NULL) {
for(i = info->files; i; i = i->next) {
dbstr = (char*)i->data;
if(dbstr == NULL || rindex(dbstr, '/') == dbstr+strlen(dbstr)-1)
continue;
for(d = 0, j = targets; j; j = j->next, d++) {
pkginfo_t *targ = (pkginfo_t*)j->data;
if(strcmp(info->name, targ->name) && strhash_isin(htables[d], dbstr)) {
MALLOC(str, 512);
snprintf(str, 512, "%s: exists in \"%s\" (target) and \"%s\" (installed)", dbstr,
targ->name, info->name);
conflicts = list_add(conflicts, str);
}
}
}
}*/
/* CHECK 2: check every target against every target */
/* CHECK 1: check every target against every target */
for(d = 0, i = targets; i; i = i->next, d++) {
pkginfo_t *p1 = (pkginfo_t*)i->data;
for(e = d, j = i; j; j = j->next, e++) {
@ -741,7 +757,7 @@ PMList* db_find_conflicts(pacdb_t *db, PMList *targets, char *root)
}
}
/* CHECK 3: check every target against the filesystem */
/* CHECK 2: check every target against the filesystem */
for(i = targets; i; i = i->next) {
pkginfo_t *p = (pkginfo_t*)i->data;
pkginfo_t *dbpkg = NULL;
@ -769,6 +785,7 @@ PMList* db_find_conflicts(pacdb_t *db, PMList *targets, char *root)
snprintf(str, PATH_MAX, "%s%s", root, (char*)k->data);
stat(str, &buf2);
if(buf.st_ino == buf2.st_ino && buf.st_dev == buf2.st_dev) {
printf("inodes match: %s and %s\n", path, str);
ok = 1;
}
}
@ -785,7 +802,26 @@ PMList* db_find_conflicts(pacdb_t *db, PMList *targets, char *root)
dbpkg2 = db_scan(db, p1->name, INFRQ_DESC | INFRQ_FILES);
/* If it used to exist in there, but doesn't anymore */
if(dbpkg2 && !is_in(filestr, p1->files) && is_in(filestr, dbpkg2->files)) {
/*printf("file %s moved from %s to %s\n", filestr, p1->name, p->name);*/
ok = 1;
/* Add to the "skip list" of files that we shouldn't remove during an upgrade.
*
* This is a workaround for the following scenario:
*
* - the old package A provides file X
* - the new package A does not
* - the new package B provides file X
* - package A depends on B, so B is upgraded first
*
* Package B is upgraded, so file X is installed. Then package A
* is upgraded, and it *removes* file X, since it no longer exists
* in package A.
*
* Our workaround is to scan through all "old" packages and all "new"
* ones, looking for files that jump to different packages.
*/
*skip_list = list_add(*skip_list, filestr);
}
FREEPKG(dbpkg2);
}
@ -801,6 +837,11 @@ PMList* db_find_conflicts(pacdb_t *db, PMList *targets, char *root)
FREEPKG(dbpkg);
}
/* free up the hash tables */
for(d = 0; d <= target_num; d++) {
free_strhash(htables[d]);
}
return(conflicts);
}

View file

@ -22,6 +22,7 @@
#define _PAC_DB_H
#include <dirent.h>
#include "strhash.h"
/* info requests for db_read */
#define INFRQ_DESC 0x01
@ -35,6 +36,9 @@ typedef struct __pacdb_t {
DIR* dir;
} pacdb_t;
/* hash table for caching db_scan() results */
static strhash_t* db_htable;
pacdb_t* db_open(char *root, char *dbpath, char *treename);
void db_close(pacdb_t *db);
int db_getlastupdate(const char *dbpath, char *ts);
@ -43,8 +47,9 @@ PMList* db_loadpkgs(pacdb_t *db);
pkginfo_t* db_scan(pacdb_t *db, char *target, unsigned int inforeq);
pkginfo_t* db_read(pacdb_t *db, struct dirent *ent, unsigned int inforeq);
int db_write(pacdb_t *db, pkginfo_t *info, unsigned int inforeq);
void db_remove(pacdb_t *db, pkginfo_t *target);
void db_search(pacdb_t *db, PMList *cache, const char *treename, PMList *needles);
PMList* db_find_conflicts(pacdb_t *db, PMList* targets, char *root);
PMList* db_find_conflicts(pacdb_t *db, PMList* targets, char *root, PMList **skip_list);
PMList *whatprovides(pacdb_t *db, char* package);
PMList *find_groups(pacdb_t *db);
PMList *pkg_ingroup(pacdb_t *db, char *group);

View file

@ -67,17 +67,14 @@ PMList* list_new()
void list_free(PMList *list)
{
if(list == NULL) {
return;
PMList *ptr, *it = list;
while(it) {
ptr = it->next;
free(it->data);
free(it);
it = ptr;
}
if(list->data != NULL) {
free(list->data);
list->data = NULL;
}
if(list->next != NULL) {
list_free(list->next);
}
free(list);
return;
}

View file

@ -22,7 +22,7 @@
#define _PAC_PACCONF_H
#ifndef PACVER
#define PACVER "2.9.5"
#define PACVER "2.9.6"
#endif
#ifndef PACDBDIR

View file

@ -240,7 +240,7 @@ int main(int argc, char *argv[])
/* start the requested operation */
switch(pmo_op) {
case PM_ADD: ret = pacman_add(db_local, pm_targets, NULL); break;
case PM_REMOVE: ret = pacman_remove(db_local, pm_targets); break;
case PM_REMOVE: ret = pacman_remove(db_local, pm_targets, NULL); break;
case PM_UPGRADE: ret = pacman_upgrade(db_local, pm_targets, NULL); break;
case PM_QUERY: ret = pacman_query(db_local, pm_targets); break;
case PM_SYNC: ret = pacman_sync(db_local, pm_targets); break;
@ -1323,7 +1323,7 @@ int pacman_sync(pacdb_t *db, PMList *targets)
int oldval = pmo_nodeps;
/* we make pacman_remove() skip dependency checks by setting pmo_nodeps high */
pmo_nodeps = 1;
retcode = pacman_remove(db, rmtargs);
retcode = pacman_remove(db, rmtargs, NULL);
pmo_nodeps = oldval;
FREELIST(rmtargs);
if(retcode == 1) {
@ -1356,7 +1356,7 @@ int pacman_sync(pacdb_t *db, PMList *targets)
int oldval = pmo_nodeps;
/* we make pacman_remove() skip dependency checks by setting pmo_nodeps high */
pmo_nodeps = 1;
allgood = !pacman_remove(db, rmtargs);
allgood = !pacman_remove(db, rmtargs, NULL);
pmo_nodeps = oldval;
if(!allgood) {
fprintf(stderr, "package removal failed. aborting...\n");
@ -1367,11 +1367,17 @@ int pacman_sync(pacdb_t *db, PMList *targets)
allgood = !pacman_upgrade(db, files, dependonly);
}
/* propagate replaced packages' requiredby fields to their new owners */
/* XXX: segfault */
if(allgood) {
for(i = final; i; i = i->next) {
syncpkg_t *sync = (syncpkg_t*)i->data;
if(sync->replaces) {
pkginfo_t *new = db_scan(db, sync->pkg->name, INFRQ_DEPENDS);
pkginfo_t *new;
new = db_scan(db, sync->pkg->name, INFRQ_DEPENDS);
if(!new) {
fprintf(stderr, "Something has gone terribly wrong. I'll probably segfault now.\n");
fflush(stderr);
}
for(j = sync->replaces; j; j = j->next) {
pkginfo_t *old = (pkginfo_t*)j->data;
/* merge lists */
@ -1448,6 +1454,8 @@ int pacman_add(pacdb_t *db, PMList *targets, PMList *dependonly)
struct stat buf;
PMList *targ, *lp, *j, *k;
PMList *alltargs = NULL;
PMList *skiplist = NULL;
unsigned short real_pmo_upgrade;
tartype_t gztype = {
(openfunc_t) gzopen_frontend,
@ -1646,7 +1654,7 @@ int pacman_add(pacdb_t *db, PMList *targets, PMList *dependonly)
alltargs = k;
/* make sure pacman_remove does it's own dependency check */
pmo_upgrade = 0;
retcode = pacman_remove(db, rmtargs);
retcode = pacman_remove(db, rmtargs, NULL);
list_free(rmtargs);
if(retcode == 1) {
fprintf(stderr, "\n%s aborted.\n", oldupg ? "upgrade" : "install");
@ -1683,7 +1691,7 @@ int pacman_add(pacdb_t *db, PMList *targets, PMList *dependonly)
if(!pmo_force) {
printf("checking for file conflicts... ");
fflush(stdout);
lp = db_find_conflicts(db, alltargs, pmo_root);
lp = db_find_conflicts(db, alltargs, pmo_root, &skiplist);
if(lp) {
printf("\nerror: the following file conflicts were found:\n");
for(j = lp; j; j = j->next) {
@ -1738,7 +1746,7 @@ int pacman_add(pacdb_t *db, PMList *targets, PMList *dependonly)
/* copy over the install reason */
info->reason = oldpkg->reason;
vprint("removing old package first...\n");
retcode = pacman_remove(db, tmp);
retcode = pacman_remove(db, tmp, skiplist);
FREELIST(tmp);
if(retcode == 1) {
fprintf(stderr, "\nupgrade aborted.\n");
@ -1793,7 +1801,20 @@ int pacman_add(pacdb_t *db, PMList *targets, PMList *dependonly)
snprintf(expath, PATH_MAX, "%s%s", pmo_root, pathname);
}
if(!stat(expath, &buf) && !S_ISDIR(buf.st_mode)) {
/* if a file is in NoUpgrade and missing from the filesystem,
* then we never extract it.
*
* eg, /home/httpd/html/index.html may be removed so index.php
* could be used
*/
if(stat(expath, &buf) && is_in(pathname, pmo_noupgrade)) {
vprint("%s is in NoUpgrade - skipping\n", pathname);
logaction(stderr, "warning: %s is in NoUpgrade -- skipping extraction", pathname);
tar_skip_regfile(tar);
continue;
}
if(!notouch && !stat(expath, &buf) && !S_ISDIR(buf.st_mode)) {
/* file already exists */
if(is_in(pathname, pmo_noupgrade)) {
notouch = 1;
@ -1916,7 +1937,6 @@ int pacman_add(pacdb_t *db, PMList *targets, PMList *dependonly)
vprint("%s is in NoUpgrade - skipping\n", pathname);
strncat(expath, ".pacnew", PATH_MAX);
logaction(stderr, "warning: extracting %s%s as %s", pmo_root, pathname, expath);
/*tar_skip_regfile(tar);*/
}
if(pmo_force) {
/* if pmo_force was used, then unlink() each file (whether it's there
@ -1980,6 +2000,7 @@ int pacman_add(pacdb_t *db, PMList *targets, PMList *dependonly)
continue;
}
}
FREEPKG(tmpp);
}
vprint("Updating database...");
@ -2019,6 +2040,7 @@ int pacman_add(pacdb_t *db, PMList *targets, PMList *dependonly)
if(provides) {
/* use the first one */
depinfo = db_scan(db, provides->data, INFRQ_DEPENDS);
FREELIST(provides);
if(depinfo == NULL) {
/* wtf */
continue;
@ -2066,7 +2088,7 @@ int pacman_add(pacdb_t *db, PMList *targets, PMList *dependonly)
return(ret);
}
int pacman_remove(pacdb_t *db, PMList *targets)
int pacman_remove(pacdb_t *db, PMList *targets, PMList *skiplist)
{
char line[PATH_MAX+1];
char pm_install[PATH_MAX+1];
@ -2137,8 +2159,17 @@ int pacman_remove(pacdb_t *db, PMList *targets)
for(j = lp; j; j = j->next) {
depmissing_t* miss = (depmissing_t*)j->data;
info = db_scan(db, miss->depend.name, INFRQ_ALL);
if(info == NULL) {
fprintf(stderr, "error: %s is not installed, even though it is required\n", miss->depend.name);
fprintf(stderr, " by an installed package (%s)\n\n", miss->target);
fprintf(stderr, "cannot complete a cascade removal with a broken dependency chain\n");
FREELISTPKGS(alltargs);
return(1);
}
if(!is_pkgin(info, alltargs)) {
alltargs = list_add(alltargs, info);
} else {
FREEPKG(info);
}
}
list_free(lp);
@ -2198,16 +2229,19 @@ int pacman_remove(pacdb_t *db, PMList *targets)
/* iterate through the list backwards, unlinking files */
for(lp = list_last(info->files); lp; lp = lp->prev) {
int nb = 0;
if(needbackup((char*)lp->data, info->backup)) {
char *file;
file = (char*)lp->data;
if(needbackup(file, info->backup)) {
nb = 1;
}
if(!nb && pmo_upgrade) {
/* check pmo_noupgrade */
if(is_in((char*)lp->data, pmo_noupgrade)) {
if(is_in(file, pmo_noupgrade)) {
nb = 1;
}
}
snprintf(line, PATH_MAX, "%s%s", pmo_root, (char*)lp->data);
snprintf(line, PATH_MAX, "%s%s", pmo_root, file);
if(lstat(line, &buf)) {
vprint("file %s does not exist\n", line);
continue;
@ -2218,27 +2252,41 @@ int pacman_remove(pacdb_t *db, PMList *targets)
/* this is okay, other packages are probably using it. */
}
} else {
/* if the file is flagged, back it up to .pacsave */
if(nb) {
if(pmo_upgrade) {
/* we're upgrading so just leave the file as is. pacman_add() will handle it */
} else {
if(!pmo_nosave) {
newpath = (char*)realloc(newpath, strlen(line)+strlen(".pacsave")+1);
sprintf(newpath, "%s.pacsave", line);
rename(line, newpath);
logaction(stderr, "warning: %s saved as %s", line, newpath);
/* check the "skip list" before removing the file
*
* see the big comment block in db_find_conflicts() for an explanation
*/
int skipit = 0;
for(j = skiplist; j; j = j->next) {
if(!strcmp(file, (char*)j->data)) {
skipit = 1;
}
}
if(skipit) {
vprint("skipping removal of %s (it has moved to another package)\n", file);
} else {
/* if the file is flagged, back it up to .pacsave */
if(nb) {
if(pmo_upgrade) {
/* we're upgrading so just leave the file as is. pacman_add() will handle it */
} else {
/*vprint(" unlinking %s\n", line);*/
if(unlink(line)) {
perror("cannot remove file");
if(!pmo_nosave) {
newpath = (char*)realloc(newpath, strlen(line)+strlen(".pacsave")+1);
sprintf(newpath, "%s.pacsave", line);
rename(line, newpath);
logaction(stderr, "warning: %s saved as %s", line, newpath);
} else {
/*vprint(" unlinking %s\n", line);*/
if(unlink(line)) {
perror("cannot remove file");
}
}
}
}
} else {
/*vprint(" unlinking %s\n", line);*/
if(unlink(line)) {
perror("cannot remove file");
} else {
/*vprint(" unlinking %s\n", line);*/
if(unlink(line)) {
perror("cannot remove file");
}
}
}
}
@ -2252,27 +2300,11 @@ int pacman_remove(pacdb_t *db, PMList *targets)
}
/* remove the package from the database */
snprintf(line, PATH_MAX, "%s%s/%s/%s-%s", pmo_root, pmo_dbpath, db->treename,
info->name, info->version);
/* DESC */
snprintf(pm_install, PATH_MAX, "%s/desc", line);
unlink(pm_install);
/* FILES */
snprintf(pm_install, PATH_MAX, "%s/files", line);
unlink(pm_install);
/* DEPENDS */
snprintf(pm_install, PATH_MAX, "%s/depends", line);
unlink(pm_install);
/* INSTALL */
snprintf(pm_install, PATH_MAX, "%s/install", line);
unlink(pm_install);
/* directory */
rmdir(line);
db_remove(db, info);
/* update dependency packages' REQUIREDBY fields */
for(lp = info->depends; lp; lp = lp->next) {
PMList *j;
PMList *k;
if(splitdep((char*)lp->data, &depend)) {
continue;
@ -2298,9 +2330,9 @@ int pacman_remove(pacdb_t *db, PMList *targets)
}
}
/* splice out this entry from requiredby */
for(j = depinfo->requiredby; j; j = j->next) {
if(!strcmp((char*)j->data, info->name)) {
depinfo->requiredby = list_remove(depinfo->requiredby, j);
for(k = depinfo->requiredby; k; k = k->next) {
if(!strcmp((char*)k->data, info->name)) {
depinfo->requiredby = list_remove(depinfo->requiredby, k);
break;
}
}
@ -2673,6 +2705,7 @@ PMList* removedeps(pacdb_t *db, PMList *targs)
FREELIST(k);
}
if(is_pkgin(dep, targs)) {
FREEPKG(dep);
continue;
}
/* see if it was explicitly installed */
@ -2687,10 +2720,11 @@ PMList* removedeps(pacdb_t *db, PMList *targs)
if(!is_pkgin(dummy, targs)) {
needed = 1;
}
FREEPKG(dummy);
}
FREEPKG(dep);
if(!needed) {
/* add it to the target list */
freepkg(dep);
dep = db_scan(db, depend.name, INFRQ_ALL);
newtargs = list_add(newtargs, dep);
newtargs = removedeps(db, newtargs);
@ -2922,6 +2956,8 @@ PMList* checkdeps(pacdb_t *db, unsigned short op, PMList *targets)
strncpy(miss->depend.version, depend.version, 64);
if(!list_isin(baddeps, miss)) {
baddeps = list_add(baddeps, miss);
} else {
FREE(miss);
}
}
FREEPKG(p);
@ -2969,6 +3005,8 @@ PMList* checkdeps(pacdb_t *db, unsigned short op, PMList *targets)
strncpy(miss->depend.name, dp->name, 256);
if(!list_isin(baddeps, miss)) {
baddeps = list_add(baddeps, miss);
} else {
FREE(miss);
}
}
}
@ -3002,6 +3040,8 @@ PMList* checkdeps(pacdb_t *db, unsigned short op, PMList *targets)
strncpy(miss->depend.name, otp->name, 256);
if(!list_isin(baddeps, miss)) {
baddeps = list_add(baddeps, miss);
} else {
FREE(miss);
}
}
}
@ -3036,6 +3076,8 @@ PMList* checkdeps(pacdb_t *db, unsigned short op, PMList *targets)
strncpy(miss->depend.name, info->name, 256);
if(!list_isin(baddeps, miss)) {
baddeps = list_add(baddeps, miss);
} else {
FREE(miss);
}
}
}
@ -3063,6 +3105,8 @@ PMList* checkdeps(pacdb_t *db, unsigned short op, PMList *targets)
strncpy(miss->depend.name, k->data, 256);
if(!list_isin(baddeps, miss)) {
baddeps = list_add(baddeps, miss);
} else {
FREE(miss);
}
}
}*/
@ -3178,6 +3222,8 @@ PMList* checkdeps(pacdb_t *db, unsigned short op, PMList *targets)
strncpy(miss->depend.version, depend.version, 64);
if(!list_isin(baddeps, miss)) {
baddeps = list_add(baddeps, miss);
} else {
FREE(miss);
}
}
}
@ -3200,6 +3246,8 @@ PMList* checkdeps(pacdb_t *db, unsigned short op, PMList *targets)
strncpy(miss->depend.name, (char*)j->data, 256);
if(!list_isin(baddeps, miss)) {
baddeps = list_add(baddeps, miss);
} else {
FREE(miss);
}
}
}
@ -3326,10 +3374,10 @@ int runscriptlet(char *installfn, char *script, char *ver, char *oldver)
vprint("Executing %s script...\n", script);
if(oldver) {
snprintf(cmdline, PATH_MAX, "echo \"umask 0022; source %s %s %s %s\" | chroot %s /bin/sh",
snprintf(cmdline, PATH_MAX, "echo \"umask 0022; source %s %s %s %s\" | /usr/sbin/chroot %s /bin/sh",
scriptpath, script, ver, oldver, pmo_root);
} else {
snprintf(cmdline, PATH_MAX, "echo \"umask 0022; source %s %s %s\" | chroot %s /bin/sh",
snprintf(cmdline, PATH_MAX, "echo \"umask 0022; source %s %s %s\" | /usr/sbin/chroot %s /bin/sh",
scriptpath, script, ver, pmo_root);
}
vprint("%s\n", cmdline);

View file

@ -33,7 +33,7 @@
#define min(X, Y) ((X) < (Y) ? (X) : (Y))
int pacman_add(pacdb_t *db, PMList *targets, PMList *dependonly);
int pacman_remove(pacdb_t *db, PMList *targets);
int pacman_remove(pacdb_t *db, PMList *targets, PMList *skiplist);
int pacman_upgrade(pacdb_t *db, PMList *targets, PMList *dependonly);
int pacman_query(pacdb_t *db, PMList *targets);
int pacman_sync(pacdb_t *db, PMList *targets);

View file

@ -441,6 +441,13 @@ int downloadfiles_forreal(PMList *servers, const char *localpath,
snprintf(completefile, PATH_MAX, "%s/%s", localpath, fn);
rename(output, completefile);
} else if(filedone < 0) {
if(!pmo_xfercommand) {
if(!strcmp(server->protocol, "ftp") && !pmo_proxyhost) {
FtpQuit(control);
} else if(!strcmp(server->protocol, "http") || (pmo_proxyhost && strcmp(server->protocol, "file"))) {
HttpQuit(control);
}
}
return(-1);
}
printf("\n");

View file

@ -1,22 +1,22 @@
/* evtgen string hash functions.
Copyright (C) 2003 Julien Olivain and LSV, CNRS UMR 8643 & ENS Cachan.
Copyright (C) 2003 Julien Olivain and LSV, CNRS UMR 8643 & ENS Cachan.
This file is part of evtgen.
This file is part of evtgen.
evtgen 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, or (at your option)
any later version.
evtgen 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, or (at your option)
any later version.
evtgen 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.
evtgen 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 evtgen; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*/
You should have received a copy of the GNU General Public License
along with evtgen; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* Copyright (C) 2004 Tommi Rantala <tommi.rantala@cs.helsinki.fi>
*
@ -24,8 +24,8 @@
*/
/*
** strhash.c -- string hash utility functions
*/
** strhash.c -- string hash utility functions
*/
#include <stdlib.h>
#include <stdio.h>
@ -35,161 +35,168 @@
#include "list.h"
#include "strhash.h"
void
strhash_add_list(strhash_t *hash, PMList* list)
void strhash_add_list(strhash_t *hash, PMList* list)
{
for(; list; list = list->next)
for(; list; list = list->next) {
strhash_add(hash, list->data, NULL);
}
}
strhash_t *
new_strhash(size_t hsize)
strhash_t* new_strhash(size_t hsize)
{
strhash_t *h;
strhash_t *h;
MALLOC(h, sizeof (strhash_t));
h->size = hsize;
h->elmts = 0;
h->hash = DEFAULT_STRHASH_FUNCTION;
MALLOC(h->htable, hsize * sizeof (strhash_elmt_t *));
memset(h->htable, 0, hsize * sizeof(strhash_elmt_t *));
MALLOC(h, sizeof(strhash_t));
h->size = hsize;
h->elmts = 0;
h->hash = DEFAULT_STRHASH_FUNCTION;
MALLOC(h->htable, hsize * sizeof(strhash_elmt_t *));
memset(h->htable, 0, hsize * sizeof(strhash_elmt_t *));
return (h);
return(h);
}
void
clear_strhash(strhash_t *hash)
void clear_strhash(strhash_t *hash)
{
int i;
strhash_elmt_t *tmp;
strhash_elmt_t *tmp_next;
int i;
strhash_elmt_t *tmp;
strhash_elmt_t *tmp_next;
for (i = 0; i < hash->size; i++)
{
tmp = hash->htable[i];
while (tmp)
{
tmp_next = tmp->next;
free(tmp);
tmp = tmp_next;
}
}
hash->elmts = 0;
memset(hash->htable, 0, hash->size * sizeof (void *));
for(i = 0; i < hash->size; i++) {
tmp = hash->htable[i];
while(tmp) {
tmp_next = tmp->next;
free(tmp);
tmp = tmp_next;
}
}
hash->elmts = 0;
memset(hash->htable, 0, hash->size * sizeof(void *));
}
void
free_strhash(strhash_t *hash)
void free_strhash(strhash_t *hash)
{
int i;
strhash_elmt_t *tmp;
strhash_elmt_t *tmp_next;
int i;
strhash_elmt_t *tmp;
strhash_elmt_t *tmp_next;
for (i = 0; i < hash->size; i++)
{
tmp = hash->htable[i];
while (tmp)
{
tmp_next = tmp->next;
free(tmp);
tmp = tmp_next;
}
}
for(i = 0; i < hash->size; i++) {
tmp = hash->htable[i];
while(tmp) {
tmp_next = tmp->next;
free(tmp);
tmp = tmp_next;
}
}
free(hash->htable);
free(hash);
free(hash->htable);
free(hash);
}
void
strhash_add(strhash_t *hash, char *key, char *data)
void strhash_add(strhash_t *hash, char *key, char *data)
{
strhash_elmt_t *elmt;
unsigned long hcode;
strhash_elmt_t *elmt;
unsigned long hcode;
MALLOC(elmt, sizeof (strhash_elmt_t));
elmt->key = key;
elmt->data = data;
MALLOC(elmt, sizeof(strhash_elmt_t));
elmt->key = key;
elmt->data = data;
hcode = hash->hash(key) % hash->size;
elmt->next = hash->htable[hcode];
hash->htable[hcode] = elmt;
hash->elmts++;
hcode = hash->hash(key) % hash->size;
elmt->next = hash->htable[hcode];
hash->htable[hcode] = elmt;
hash->elmts++;
}
void strhash_remove(strhash_t *hash, char *key)
{
unsigned long hcode;
strhash_elmt_t *elmt;
strhash_elmt_t *prev = NULL;
hcode = hash->hash(key) % hash->size;
elmt = hash->htable[hcode];
for(; elmt; elmt = elmt->next) {
if(!strcmp(key, elmt->key)) {
if(prev) {
prev->next = elmt->next;
} else {
hash->htable[hcode] = elmt->next;
}
FREE(elmt);
return;
}
prev = elmt;
}
}
/* 1: Yes, the key exists in the hash table.
* 0: No, its not here.
* 0: No, it's not here.
*/
int
strhash_isin(strhash_t *hash, char* key)
int strhash_isin(strhash_t *hash, char* key)
{
strhash_elmt_t *elmt;
strhash_elmt_t *elmt;
elmt = hash->htable[hash->hash(key) % hash->size];
for (; elmt; elmt = elmt->next)
{
if (!strcmp(key, elmt->key))
return 1;
}
elmt = hash->htable[hash->hash(key) % hash->size];
for(; elmt; elmt = elmt->next) {
if(!strcmp(key, elmt->key)) {
return 1;
}
}
return 0;
return 0;
}
char*
strhash_get(strhash_t *hash, char* key)
char* strhash_get(strhash_t *hash, char* key)
{
strhash_elmt_t *elmt;
strhash_elmt_t *elmt;
elmt = hash->htable[hash->hash(key) % hash->size];
for (; elmt; elmt = elmt->next)
{
if (!strcmp(key, elmt->key))
return elmt->data;
}
elmt = hash->htable[hash->hash(key) % hash->size];
for(; elmt; elmt = elmt->next) {
if(!strcmp(key, elmt->key)) {
return elmt->data;
}
}
return NULL;
return NULL;
}
/*
** fast hash function samples
*/
unsigned long
strhash_pjw(char *key)
** fast hash function samples
*/
unsigned long strhash_pjw(char *key)
{
unsigned long h;
unsigned long g;
unsigned long h;
unsigned long g;
h = 0;
while (*key)
{
h = (h << 4) + *key++;
if ((g = h & 0xF0000000U) != 0)
{
h = h ^ (g >> 24);
h = h ^ g;
}
}
h = 0;
while(*key) {
h = (h << 4) + *key++;
if((g = h & 0xF0000000U) != 0) {
h = h ^ (g >> 24);
h = h ^ g;
}
}
return (h);
return (h);
}
int
strhash_collide_count(strhash_t *hash)
int strhash_collide_count(strhash_t *hash)
{
int count;
int i;
int count;
int i;
count = 0;
for (i = 0; i < hash->size; i++)
{
strhash_elmt_t *tmp;
count = 0;
for(i = 0; i < hash->size; i++) {
strhash_elmt_t *tmp;
for (tmp = hash->htable[i]; tmp; tmp = tmp->next)
if (tmp->next)
count++;
}
for(tmp = hash->htable[i]; tmp; tmp = tmp->next) {
if(tmp->next) {
count++;
}
}
}
return (count);
return(count);
}

View file

@ -55,6 +55,7 @@ void strhash_add_list(strhash_t *hash, PMList* list);
strhash_t *new_strhash(size_t hsize);
void free_strhash(strhash_t *hash);
void clear_strhash(strhash_t *hash);
void strhash_remove(strhash_t *hash, char *key);
void strhash_add(strhash_t *hash, char *key, char *data);
int strhash_isin(strhash_t *hash, char* key);
char* strhash_get(strhash_t *hash, char* key);