Imported from pacman-2.9.6.tar.gz
This commit is contained in:
parent
d48cc3bf5d
commit
d05f0047a0
18 changed files with 489 additions and 254 deletions
11
ChangeLog
11
ChangeLog
|
@ -1,5 +1,16 @@
|
||||||
VERSION DESCRIPTION
|
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
|
2.9.5 - bugfix: missing files after re-ordering packages wrt
|
||||||
deps with --upgrade
|
deps with --upgrade
|
||||||
- added "Repository" line to -Si output
|
- added "Repository" line to -Si output
|
||||||
|
|
|
@ -34,7 +34,7 @@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
|
||||||
INSTALL_DATA = @INSTALL_DATA@
|
INSTALL_DATA = @INSTALL_DATA@
|
||||||
INSTALL_SCRIPT = @INSTALL_SCRIPT@
|
INSTALL_SCRIPT = @INSTALL_SCRIPT@
|
||||||
|
|
||||||
PACVER = 2.9.5
|
PACVER = 2.9.6
|
||||||
|
|
||||||
TOPDIR = @srcdir@
|
TOPDIR = @srcdir@
|
||||||
SRCDIR = $(TOPDIR)/src/
|
SRCDIR = $(TOPDIR)/src/
|
||||||
|
@ -106,6 +106,7 @@ install: pacman vercmp convertdb man
|
||||||
$(INSTALL) -D -m0755 $(SCRDIR)makeworld $(DESTDIR)$(BINDIR)/makeworld
|
$(INSTALL) -D -m0755 $(SCRDIR)makeworld $(DESTDIR)$(BINDIR)/makeworld
|
||||||
$(INSTALL) -D -m0755 $(SCRDIR)gensync $(DESTDIR)$(BINDIR)/gensync
|
$(INSTALL) -D -m0755 $(SCRDIR)gensync $(DESTDIR)$(BINDIR)/gensync
|
||||||
$(INSTALL) -D -m0755 $(SCRDIR)updatesync $(DESTDIR)$(BINDIR)/updatesync
|
$(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)pacman.8 $(DESTDIR)$(MANDIR)/man8/pacman.8
|
||||||
$(INSTALL) -D -m0644 $(MANSRC)makepkg.8 $(DESTDIR)$(MANDIR)/man8/makepkg.8
|
$(INSTALL) -D -m0644 $(MANSRC)makepkg.8 $(DESTDIR)$(MANDIR)/man8/makepkg.8
|
||||||
$(INSTALL) -D -m0644 etc/pacman.conf $(DESTDIR)/etc/pacman.conf
|
$(INSTALL) -D -m0644 etc/pacman.conf $(DESTDIR)/etc/pacman.conf
|
||||||
|
|
|
@ -81,7 +81,7 @@ Output more status and error messages.
|
||||||
Specify an alternate configuration file.
|
Specify an alternate configuration file.
|
||||||
.TP
|
.TP
|
||||||
.B "\-\-noconfirm"
|
.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.
|
unless you want to run pacman from a script.
|
||||||
.SH SYNC OPTIONS
|
.SH SYNC OPTIONS
|
||||||
.TP
|
.TP
|
||||||
|
|
|
@ -12,8 +12,8 @@ export CHOST="i686-pc-linux-gnu"
|
||||||
|
|
||||||
# Pentium Pro/Pentium II/Pentium III+/Pentium 4/Athlon exclusive (binaries
|
# Pentium Pro/Pentium II/Pentium III+/Pentium 4/Athlon exclusive (binaries
|
||||||
# will use the P6 instruction set and only run on P6+ systems)
|
# will use the P6 instruction set and only run on P6+ systems)
|
||||||
export CFLAGS="-march=i686 -O2 -pipe"
|
export CFLAGS="-march=i686 -O2 -pipe -Wl,-O1"
|
||||||
export CXXFLAGS="-march=i686 -O2 -pipe"
|
export CXXFLAGS="-march=i686 -O2 -pipe -Wl,-O1"
|
||||||
# Pentium Pro/Pentium II/Pentium III+/Pentium 4/Athlon optimized (but binaries
|
# Pentium Pro/Pentium II/Pentium III+/Pentium 4/Athlon optimized (but binaries
|
||||||
# will run on any x86 system)
|
# will run on any x86 system)
|
||||||
#export CFLAGS="-mcpu=i686 -O2 -pipe"
|
#export CFLAGS="-mcpu=i686 -O2 -pipe"
|
||||||
|
@ -26,7 +26,7 @@ export CXXFLAGS="-march=i686 -O2 -pipe"
|
||||||
export USE_FAKEROOT="y"
|
export USE_FAKEROOT="y"
|
||||||
|
|
||||||
# Enable colorized output messages
|
# Enable colorized output messages
|
||||||
export USE_COLOR="n"
|
export USE_COLOR="y"
|
||||||
|
|
||||||
# Specify a fixed directory where all packages will be placed
|
# Specify a fixed directory where all packages will be placed
|
||||||
#export PKGDEST=/home/packages
|
#export PKGDEST=/home/packages
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
#
|
#
|
||||||
# gensync
|
# 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
|
# 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
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
@ -20,7 +20,7 @@
|
||||||
# USA.
|
# USA.
|
||||||
#
|
#
|
||||||
|
|
||||||
myver='2.9.2'
|
myver='2.9.6'
|
||||||
|
|
||||||
usage() {
|
usage() {
|
||||||
echo "gensync $myver"
|
echo "gensync $myver"
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
#
|
#
|
||||||
# makepkg
|
# 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
|
# 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
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
@ -20,7 +20,7 @@
|
||||||
# USA.
|
# USA.
|
||||||
#
|
#
|
||||||
|
|
||||||
myver='2.9.2'
|
myver='2.9.6'
|
||||||
startdir=`pwd`
|
startdir=`pwd`
|
||||||
PKGDEST=$startdir
|
PKGDEST=$startdir
|
||||||
USE_COLOR="n"
|
USE_COLOR="n"
|
||||||
|
@ -357,7 +357,7 @@ if [ "`id -u`" != "0" ]; then
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
msg "Making package: $pkgname (`date`)"
|
msg "Making package: $pkgname $pkgver-$pkgrel (`date`)"
|
||||||
|
|
||||||
unset deplist makedeplist
|
unset deplist makedeplist
|
||||||
if [ `type -p pacman` -a "$NODEPS" = "0" ]; then
|
if [ `type -p pacman` -a "$NODEPS" = "0" ]; then
|
||||||
|
@ -552,6 +552,9 @@ if [ "$NOBUILD" = "1" ]; then
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# use ccache if it's available
|
||||||
|
[ -d /usr/lib/ccache/bin ] && export PATH=/usr/lib/ccache/bin:$PATH
|
||||||
|
|
||||||
# build
|
# build
|
||||||
msg "Starting build()..."
|
msg "Starting build()..."
|
||||||
build 2>&1
|
build 2>&1
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
#
|
#
|
||||||
# makeworld
|
# 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
|
# 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
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
@ -20,8 +20,8 @@
|
||||||
# USA.
|
# USA.
|
||||||
#
|
#
|
||||||
|
|
||||||
|
version="2.9.6"
|
||||||
toplevel=`pwd`
|
toplevel=`pwd`
|
||||||
version="2.9.2"
|
|
||||||
|
|
||||||
usage() {
|
usage() {
|
||||||
echo "makeworld version $version"
|
echo "makeworld version $version"
|
||||||
|
@ -106,12 +106,12 @@ fi
|
||||||
# convert a (possibly) relative path to absolute
|
# convert a (possibly) relative path to absolute
|
||||||
cd $dest
|
cd $dest
|
||||||
dest=`pwd`
|
dest=`pwd`
|
||||||
cd -
|
cd - &>/dev/null
|
||||||
|
|
||||||
sd=`date +"[%b %d %H:%M]"`
|
sd=`date +"[%b %d %H:%M]"`
|
||||||
|
|
||||||
for category in $*; do
|
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
|
cd $port
|
||||||
if [ -f PKGBUILD ]; then
|
if [ -f PKGBUILD ]; then
|
||||||
. PKGBUILD
|
. PKGBUILD
|
||||||
|
|
114
scripts/pacman-optimize
Executable file
114
scripts/pacman-optimize
Executable 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
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
# updatesync
|
# updatesync
|
||||||
#
|
#
|
||||||
# Copyright (c) 2004 by Jason Chu <jason@archlinux.org>
|
# 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
|
# 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
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
@ -21,7 +21,7 @@
|
||||||
# USA.
|
# USA.
|
||||||
#
|
#
|
||||||
|
|
||||||
myver='2.9.2'
|
myver='2.9.6'
|
||||||
|
|
||||||
usage() {
|
usage() {
|
||||||
echo "updatesync $myver"
|
echo "updatesync $myver"
|
||||||
|
|
125
src/db.c
125
src/db.c
|
@ -137,21 +137,32 @@ pkginfo_t* db_scan(pacdb_t *db, char *target, unsigned int inforeq)
|
||||||
char *ptr = NULL;
|
char *ptr = NULL;
|
||||||
int found = 0;
|
int found = 0;
|
||||||
|
|
||||||
/* hash table for caching directory names */
|
/* initialize the hash table */
|
||||||
static strhash_t* htable = NULL;
|
if(!db_htable) {
|
||||||
|
db_htable = new_strhash(951);
|
||||||
if (!htable)
|
}
|
||||||
htable = new_strhash(951);
|
|
||||||
|
|
||||||
snprintf(path, PATH_MAX, "%s/", db->path);
|
snprintf(path, PATH_MAX, "%s/", db->path);
|
||||||
path_len = strlen(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) {
|
if(target != NULL) {
|
||||||
/* search for a specific package (by name only) */
|
/* search for a specific package (by name only) */
|
||||||
|
|
||||||
/* See if we have the path cached. */
|
/* See if we have the path cached. */
|
||||||
strcat(path, target);
|
strcat(path, target);
|
||||||
if (strhash_isin(htable, path)) {
|
if(strhash_isin(db_htable, path)) {
|
||||||
struct dirent* pkgdir;
|
struct dirent* pkgdir;
|
||||||
pkginfo_t* pkg;
|
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. */
|
* Actually it only uses the d_name field. */
|
||||||
|
|
||||||
MALLOC(pkgdir, sizeof(struct dirent));
|
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);
|
pkg = db_read(db, pkgdir, inforeq);
|
||||||
FREE(pkgdir);
|
FREE(pkgdir);
|
||||||
|
@ -242,8 +253,8 @@ pkginfo_t* db_scan(pacdb_t *db, char *target, unsigned int inforeq)
|
||||||
* data: xrally-1.1.1-1
|
* data: xrally-1.1.1-1
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (!strhash_isin(htable, path)) {
|
if(!strhash_isin(db_htable, path)) {
|
||||||
strhash_add(htable, strdup(path), strdup(ent->d_name));
|
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);
|
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)
|
void db_search(pacdb_t *db, PMList *cache, const char *treename, PMList *needles)
|
||||||
{
|
{
|
||||||
PMList *i, *j;
|
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;
|
PMList *i, *j, *k;
|
||||||
char *filestr = NULL;
|
char *filestr = NULL;
|
||||||
|
@ -663,6 +708,7 @@ PMList* db_find_conflicts(pacdb_t *db, PMList *targets, char *root)
|
||||||
char *str = NULL;
|
char *str = NULL;
|
||||||
struct stat buf, buf2;
|
struct stat buf, buf2;
|
||||||
PMList *conflicts = NULL;
|
PMList *conflicts = NULL;
|
||||||
|
|
||||||
strhash_t** htables;
|
strhash_t** htables;
|
||||||
int target_num = 0;
|
int target_num = 0;
|
||||||
int d = 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++) {
|
for(d = 0, i = targets; i; i = i->next, d++) {
|
||||||
htables[d] = new_strhash(151);
|
htables[d] = new_strhash(151);
|
||||||
|
|
||||||
strhash_add_list(htables[d], ((pkginfo_t*)i->data)->files);
|
strhash_add_list(htables[d], ((pkginfo_t*)i->data)->files);
|
||||||
}
|
}
|
||||||
|
|
||||||
htables[target_num] = new_strhash(151);
|
htables[target_num] = new_strhash(151);
|
||||||
|
|
||||||
/* CHECK 1: check every db package against every target package */
|
/* CHECK 1: check every target against every target */
|
||||||
/* 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 */
|
|
||||||
for(d = 0, i = targets; i; i = i->next, d++) {
|
for(d = 0, i = targets; i; i = i->next, d++) {
|
||||||
pkginfo_t *p1 = (pkginfo_t*)i->data;
|
pkginfo_t *p1 = (pkginfo_t*)i->data;
|
||||||
for(e = d, j = i; j; j = j->next, e++) {
|
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) {
|
for(i = targets; i; i = i->next) {
|
||||||
pkginfo_t *p = (pkginfo_t*)i->data;
|
pkginfo_t *p = (pkginfo_t*)i->data;
|
||||||
pkginfo_t *dbpkg = NULL;
|
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);
|
snprintf(str, PATH_MAX, "%s%s", root, (char*)k->data);
|
||||||
stat(str, &buf2);
|
stat(str, &buf2);
|
||||||
if(buf.st_ino == buf2.st_ino && buf.st_dev == buf2.st_dev) {
|
if(buf.st_ino == buf2.st_ino && buf.st_dev == buf2.st_dev) {
|
||||||
|
printf("inodes match: %s and %s\n", path, str);
|
||||||
ok = 1;
|
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);
|
dbpkg2 = db_scan(db, p1->name, INFRQ_DESC | INFRQ_FILES);
|
||||||
/* If it used to exist in there, but doesn't anymore */
|
/* If it used to exist in there, but doesn't anymore */
|
||||||
if(dbpkg2 && !is_in(filestr, p1->files) && is_in(filestr, dbpkg2->files)) {
|
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;
|
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);
|
FREEPKG(dbpkg2);
|
||||||
}
|
}
|
||||||
|
@ -801,6 +837,11 @@ PMList* db_find_conflicts(pacdb_t *db, PMList *targets, char *root)
|
||||||
FREEPKG(dbpkg);
|
FREEPKG(dbpkg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* free up the hash tables */
|
||||||
|
for(d = 0; d <= target_num; d++) {
|
||||||
|
free_strhash(htables[d]);
|
||||||
|
}
|
||||||
|
|
||||||
return(conflicts);
|
return(conflicts);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
7
src/db.h
7
src/db.h
|
@ -22,6 +22,7 @@
|
||||||
#define _PAC_DB_H
|
#define _PAC_DB_H
|
||||||
|
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
|
#include "strhash.h"
|
||||||
|
|
||||||
/* info requests for db_read */
|
/* info requests for db_read */
|
||||||
#define INFRQ_DESC 0x01
|
#define INFRQ_DESC 0x01
|
||||||
|
@ -35,6 +36,9 @@ typedef struct __pacdb_t {
|
||||||
DIR* dir;
|
DIR* dir;
|
||||||
} pacdb_t;
|
} pacdb_t;
|
||||||
|
|
||||||
|
/* hash table for caching db_scan() results */
|
||||||
|
static strhash_t* db_htable;
|
||||||
|
|
||||||
pacdb_t* db_open(char *root, char *dbpath, char *treename);
|
pacdb_t* db_open(char *root, char *dbpath, char *treename);
|
||||||
void db_close(pacdb_t *db);
|
void db_close(pacdb_t *db);
|
||||||
int db_getlastupdate(const char *dbpath, char *ts);
|
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_scan(pacdb_t *db, char *target, unsigned int inforeq);
|
||||||
pkginfo_t* db_read(pacdb_t *db, struct dirent *ent, 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);
|
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);
|
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 *whatprovides(pacdb_t *db, char* package);
|
||||||
PMList *find_groups(pacdb_t *db);
|
PMList *find_groups(pacdb_t *db);
|
||||||
PMList *pkg_ingroup(pacdb_t *db, char *group);
|
PMList *pkg_ingroup(pacdb_t *db, char *group);
|
||||||
|
|
17
src/list.c
17
src/list.c
|
@ -67,17 +67,14 @@ PMList* list_new()
|
||||||
|
|
||||||
void list_free(PMList *list)
|
void list_free(PMList *list)
|
||||||
{
|
{
|
||||||
if(list == NULL) {
|
PMList *ptr, *it = list;
|
||||||
return;
|
|
||||||
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
#define _PAC_PACCONF_H
|
#define _PAC_PACCONF_H
|
||||||
|
|
||||||
#ifndef PACVER
|
#ifndef PACVER
|
||||||
#define PACVER "2.9.5"
|
#define PACVER "2.9.6"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef PACDBDIR
|
#ifndef PACDBDIR
|
||||||
|
|
122
src/pacman.c
122
src/pacman.c
|
@ -240,7 +240,7 @@ int main(int argc, char *argv[])
|
||||||
/* start the requested operation */
|
/* start the requested operation */
|
||||||
switch(pmo_op) {
|
switch(pmo_op) {
|
||||||
case PM_ADD: ret = pacman_add(db_local, pm_targets, NULL); break;
|
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_UPGRADE: ret = pacman_upgrade(db_local, pm_targets, NULL); break;
|
||||||
case PM_QUERY: ret = pacman_query(db_local, pm_targets); break;
|
case PM_QUERY: ret = pacman_query(db_local, pm_targets); break;
|
||||||
case PM_SYNC: ret = pacman_sync(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;
|
int oldval = pmo_nodeps;
|
||||||
/* we make pacman_remove() skip dependency checks by setting pmo_nodeps high */
|
/* we make pacman_remove() skip dependency checks by setting pmo_nodeps high */
|
||||||
pmo_nodeps = 1;
|
pmo_nodeps = 1;
|
||||||
retcode = pacman_remove(db, rmtargs);
|
retcode = pacman_remove(db, rmtargs, NULL);
|
||||||
pmo_nodeps = oldval;
|
pmo_nodeps = oldval;
|
||||||
FREELIST(rmtargs);
|
FREELIST(rmtargs);
|
||||||
if(retcode == 1) {
|
if(retcode == 1) {
|
||||||
|
@ -1356,7 +1356,7 @@ int pacman_sync(pacdb_t *db, PMList *targets)
|
||||||
int oldval = pmo_nodeps;
|
int oldval = pmo_nodeps;
|
||||||
/* we make pacman_remove() skip dependency checks by setting pmo_nodeps high */
|
/* we make pacman_remove() skip dependency checks by setting pmo_nodeps high */
|
||||||
pmo_nodeps = 1;
|
pmo_nodeps = 1;
|
||||||
allgood = !pacman_remove(db, rmtargs);
|
allgood = !pacman_remove(db, rmtargs, NULL);
|
||||||
pmo_nodeps = oldval;
|
pmo_nodeps = oldval;
|
||||||
if(!allgood) {
|
if(!allgood) {
|
||||||
fprintf(stderr, "package removal failed. aborting...\n");
|
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);
|
allgood = !pacman_upgrade(db, files, dependonly);
|
||||||
}
|
}
|
||||||
/* propagate replaced packages' requiredby fields to their new owners */
|
/* propagate replaced packages' requiredby fields to their new owners */
|
||||||
|
/* XXX: segfault */
|
||||||
if(allgood) {
|
if(allgood) {
|
||||||
for(i = final; i; i = i->next) {
|
for(i = final; i; i = i->next) {
|
||||||
syncpkg_t *sync = (syncpkg_t*)i->data;
|
syncpkg_t *sync = (syncpkg_t*)i->data;
|
||||||
if(sync->replaces) {
|
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) {
|
for(j = sync->replaces; j; j = j->next) {
|
||||||
pkginfo_t *old = (pkginfo_t*)j->data;
|
pkginfo_t *old = (pkginfo_t*)j->data;
|
||||||
/* merge lists */
|
/* merge lists */
|
||||||
|
@ -1448,6 +1454,8 @@ int pacman_add(pacdb_t *db, PMList *targets, PMList *dependonly)
|
||||||
struct stat buf;
|
struct stat buf;
|
||||||
PMList *targ, *lp, *j, *k;
|
PMList *targ, *lp, *j, *k;
|
||||||
PMList *alltargs = NULL;
|
PMList *alltargs = NULL;
|
||||||
|
PMList *skiplist = NULL;
|
||||||
|
|
||||||
unsigned short real_pmo_upgrade;
|
unsigned short real_pmo_upgrade;
|
||||||
tartype_t gztype = {
|
tartype_t gztype = {
|
||||||
(openfunc_t) gzopen_frontend,
|
(openfunc_t) gzopen_frontend,
|
||||||
|
@ -1646,7 +1654,7 @@ int pacman_add(pacdb_t *db, PMList *targets, PMList *dependonly)
|
||||||
alltargs = k;
|
alltargs = k;
|
||||||
/* make sure pacman_remove does it's own dependency check */
|
/* make sure pacman_remove does it's own dependency check */
|
||||||
pmo_upgrade = 0;
|
pmo_upgrade = 0;
|
||||||
retcode = pacman_remove(db, rmtargs);
|
retcode = pacman_remove(db, rmtargs, NULL);
|
||||||
list_free(rmtargs);
|
list_free(rmtargs);
|
||||||
if(retcode == 1) {
|
if(retcode == 1) {
|
||||||
fprintf(stderr, "\n%s aborted.\n", oldupg ? "upgrade" : "install");
|
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) {
|
if(!pmo_force) {
|
||||||
printf("checking for file conflicts... ");
|
printf("checking for file conflicts... ");
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
lp = db_find_conflicts(db, alltargs, pmo_root);
|
lp = db_find_conflicts(db, alltargs, pmo_root, &skiplist);
|
||||||
if(lp) {
|
if(lp) {
|
||||||
printf("\nerror: the following file conflicts were found:\n");
|
printf("\nerror: the following file conflicts were found:\n");
|
||||||
for(j = lp; j; j = j->next) {
|
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 */
|
/* copy over the install reason */
|
||||||
info->reason = oldpkg->reason;
|
info->reason = oldpkg->reason;
|
||||||
vprint("removing old package first...\n");
|
vprint("removing old package first...\n");
|
||||||
retcode = pacman_remove(db, tmp);
|
retcode = pacman_remove(db, tmp, skiplist);
|
||||||
FREELIST(tmp);
|
FREELIST(tmp);
|
||||||
if(retcode == 1) {
|
if(retcode == 1) {
|
||||||
fprintf(stderr, "\nupgrade aborted.\n");
|
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);
|
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 */
|
/* file already exists */
|
||||||
if(is_in(pathname, pmo_noupgrade)) {
|
if(is_in(pathname, pmo_noupgrade)) {
|
||||||
notouch = 1;
|
notouch = 1;
|
||||||
|
@ -1916,7 +1937,6 @@ int pacman_add(pacdb_t *db, PMList *targets, PMList *dependonly)
|
||||||
vprint("%s is in NoUpgrade - skipping\n", pathname);
|
vprint("%s is in NoUpgrade - skipping\n", pathname);
|
||||||
strncat(expath, ".pacnew", PATH_MAX);
|
strncat(expath, ".pacnew", PATH_MAX);
|
||||||
logaction(stderr, "warning: extracting %s%s as %s", pmo_root, pathname, expath);
|
logaction(stderr, "warning: extracting %s%s as %s", pmo_root, pathname, expath);
|
||||||
/*tar_skip_regfile(tar);*/
|
|
||||||
}
|
}
|
||||||
if(pmo_force) {
|
if(pmo_force) {
|
||||||
/* if pmo_force was used, then unlink() each file (whether it's there
|
/* 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;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
FREEPKG(tmpp);
|
||||||
}
|
}
|
||||||
|
|
||||||
vprint("Updating database...");
|
vprint("Updating database...");
|
||||||
|
@ -2019,6 +2040,7 @@ int pacman_add(pacdb_t *db, PMList *targets, PMList *dependonly)
|
||||||
if(provides) {
|
if(provides) {
|
||||||
/* use the first one */
|
/* use the first one */
|
||||||
depinfo = db_scan(db, provides->data, INFRQ_DEPENDS);
|
depinfo = db_scan(db, provides->data, INFRQ_DEPENDS);
|
||||||
|
FREELIST(provides);
|
||||||
if(depinfo == NULL) {
|
if(depinfo == NULL) {
|
||||||
/* wtf */
|
/* wtf */
|
||||||
continue;
|
continue;
|
||||||
|
@ -2066,7 +2088,7 @@ int pacman_add(pacdb_t *db, PMList *targets, PMList *dependonly)
|
||||||
return(ret);
|
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 line[PATH_MAX+1];
|
||||||
char pm_install[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) {
|
for(j = lp; j; j = j->next) {
|
||||||
depmissing_t* miss = (depmissing_t*)j->data;
|
depmissing_t* miss = (depmissing_t*)j->data;
|
||||||
info = db_scan(db, miss->depend.name, INFRQ_ALL);
|
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)) {
|
if(!is_pkgin(info, alltargs)) {
|
||||||
alltargs = list_add(alltargs, info);
|
alltargs = list_add(alltargs, info);
|
||||||
|
} else {
|
||||||
|
FREEPKG(info);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
list_free(lp);
|
list_free(lp);
|
||||||
|
@ -2198,16 +2229,19 @@ int pacman_remove(pacdb_t *db, PMList *targets)
|
||||||
/* iterate through the list backwards, unlinking files */
|
/* iterate through the list backwards, unlinking files */
|
||||||
for(lp = list_last(info->files); lp; lp = lp->prev) {
|
for(lp = list_last(info->files); lp; lp = lp->prev) {
|
||||||
int nb = 0;
|
int nb = 0;
|
||||||
if(needbackup((char*)lp->data, info->backup)) {
|
char *file;
|
||||||
|
|
||||||
|
file = (char*)lp->data;
|
||||||
|
if(needbackup(file, info->backup)) {
|
||||||
nb = 1;
|
nb = 1;
|
||||||
}
|
}
|
||||||
if(!nb && pmo_upgrade) {
|
if(!nb && pmo_upgrade) {
|
||||||
/* check pmo_noupgrade */
|
/* check pmo_noupgrade */
|
||||||
if(is_in((char*)lp->data, pmo_noupgrade)) {
|
if(is_in(file, pmo_noupgrade)) {
|
||||||
nb = 1;
|
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)) {
|
if(lstat(line, &buf)) {
|
||||||
vprint("file %s does not exist\n", line);
|
vprint("file %s does not exist\n", line);
|
||||||
continue;
|
continue;
|
||||||
|
@ -2217,6 +2251,19 @@ int pacman_remove(pacdb_t *db, PMList *targets)
|
||||||
if(rmdir(line)) {
|
if(rmdir(line)) {
|
||||||
/* this is okay, other packages are probably using it. */
|
/* this is okay, other packages are probably using it. */
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
/* 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 {
|
} else {
|
||||||
/* if the file is flagged, back it up to .pacsave */
|
/* if the file is flagged, back it up to .pacsave */
|
||||||
if(nb) {
|
if(nb) {
|
||||||
|
@ -2244,6 +2291,7 @@ int pacman_remove(pacdb_t *db, PMList *targets)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(!pmo_upgrade) {
|
if(!pmo_upgrade) {
|
||||||
/* run the post-remove script if it exists */
|
/* run the post-remove script if it exists */
|
||||||
|
@ -2252,27 +2300,11 @@ int pacman_remove(pacdb_t *db, PMList *targets)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* remove the package from the database */
|
/* remove the package from the database */
|
||||||
snprintf(line, PATH_MAX, "%s%s/%s/%s-%s", pmo_root, pmo_dbpath, db->treename,
|
db_remove(db, info);
|
||||||
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);
|
|
||||||
|
|
||||||
/* update dependency packages' REQUIREDBY fields */
|
/* update dependency packages' REQUIREDBY fields */
|
||||||
for(lp = info->depends; lp; lp = lp->next) {
|
for(lp = info->depends; lp; lp = lp->next) {
|
||||||
PMList *j;
|
PMList *k;
|
||||||
|
|
||||||
if(splitdep((char*)lp->data, &depend)) {
|
if(splitdep((char*)lp->data, &depend)) {
|
||||||
continue;
|
continue;
|
||||||
|
@ -2298,9 +2330,9 @@ int pacman_remove(pacdb_t *db, PMList *targets)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* splice out this entry from requiredby */
|
/* splice out this entry from requiredby */
|
||||||
for(j = depinfo->requiredby; j; j = j->next) {
|
for(k = depinfo->requiredby; k; k = k->next) {
|
||||||
if(!strcmp((char*)j->data, info->name)) {
|
if(!strcmp((char*)k->data, info->name)) {
|
||||||
depinfo->requiredby = list_remove(depinfo->requiredby, j);
|
depinfo->requiredby = list_remove(depinfo->requiredby, k);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2673,6 +2705,7 @@ PMList* removedeps(pacdb_t *db, PMList *targs)
|
||||||
FREELIST(k);
|
FREELIST(k);
|
||||||
}
|
}
|
||||||
if(is_pkgin(dep, targs)) {
|
if(is_pkgin(dep, targs)) {
|
||||||
|
FREEPKG(dep);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
/* see if it was explicitly installed */
|
/* see if it was explicitly installed */
|
||||||
|
@ -2687,10 +2720,11 @@ PMList* removedeps(pacdb_t *db, PMList *targs)
|
||||||
if(!is_pkgin(dummy, targs)) {
|
if(!is_pkgin(dummy, targs)) {
|
||||||
needed = 1;
|
needed = 1;
|
||||||
}
|
}
|
||||||
|
FREEPKG(dummy);
|
||||||
}
|
}
|
||||||
|
FREEPKG(dep);
|
||||||
if(!needed) {
|
if(!needed) {
|
||||||
/* add it to the target list */
|
/* add it to the target list */
|
||||||
freepkg(dep);
|
|
||||||
dep = db_scan(db, depend.name, INFRQ_ALL);
|
dep = db_scan(db, depend.name, INFRQ_ALL);
|
||||||
newtargs = list_add(newtargs, dep);
|
newtargs = list_add(newtargs, dep);
|
||||||
newtargs = removedeps(db, newtargs);
|
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);
|
strncpy(miss->depend.version, depend.version, 64);
|
||||||
if(!list_isin(baddeps, miss)) {
|
if(!list_isin(baddeps, miss)) {
|
||||||
baddeps = list_add(baddeps, miss);
|
baddeps = list_add(baddeps, miss);
|
||||||
|
} else {
|
||||||
|
FREE(miss);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
FREEPKG(p);
|
FREEPKG(p);
|
||||||
|
@ -2969,6 +3005,8 @@ PMList* checkdeps(pacdb_t *db, unsigned short op, PMList *targets)
|
||||||
strncpy(miss->depend.name, dp->name, 256);
|
strncpy(miss->depend.name, dp->name, 256);
|
||||||
if(!list_isin(baddeps, miss)) {
|
if(!list_isin(baddeps, miss)) {
|
||||||
baddeps = list_add(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);
|
strncpy(miss->depend.name, otp->name, 256);
|
||||||
if(!list_isin(baddeps, miss)) {
|
if(!list_isin(baddeps, miss)) {
|
||||||
baddeps = list_add(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);
|
strncpy(miss->depend.name, info->name, 256);
|
||||||
if(!list_isin(baddeps, miss)) {
|
if(!list_isin(baddeps, miss)) {
|
||||||
baddeps = list_add(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);
|
strncpy(miss->depend.name, k->data, 256);
|
||||||
if(!list_isin(baddeps, miss)) {
|
if(!list_isin(baddeps, miss)) {
|
||||||
baddeps = list_add(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);
|
strncpy(miss->depend.version, depend.version, 64);
|
||||||
if(!list_isin(baddeps, miss)) {
|
if(!list_isin(baddeps, miss)) {
|
||||||
baddeps = list_add(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);
|
strncpy(miss->depend.name, (char*)j->data, 256);
|
||||||
if(!list_isin(baddeps, miss)) {
|
if(!list_isin(baddeps, miss)) {
|
||||||
baddeps = list_add(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);
|
vprint("Executing %s script...\n", script);
|
||||||
if(oldver) {
|
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);
|
scriptpath, script, ver, oldver, pmo_root);
|
||||||
} else {
|
} 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);
|
scriptpath, script, ver, pmo_root);
|
||||||
}
|
}
|
||||||
vprint("%s\n", cmdline);
|
vprint("%s\n", cmdline);
|
||||||
|
|
|
@ -33,7 +33,7 @@
|
||||||
#define min(X, Y) ((X) < (Y) ? (X) : (Y))
|
#define min(X, Y) ((X) < (Y) ? (X) : (Y))
|
||||||
|
|
||||||
int pacman_add(pacdb_t *db, PMList *targets, PMList *dependonly);
|
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_upgrade(pacdb_t *db, PMList *targets, PMList *dependonly);
|
||||||
int pacman_query(pacdb_t *db, PMList *targets);
|
int pacman_query(pacdb_t *db, PMList *targets);
|
||||||
int pacman_sync(pacdb_t *db, PMList *targets);
|
int pacman_sync(pacdb_t *db, PMList *targets);
|
||||||
|
|
|
@ -441,6 +441,13 @@ int downloadfiles_forreal(PMList *servers, const char *localpath,
|
||||||
snprintf(completefile, PATH_MAX, "%s/%s", localpath, fn);
|
snprintf(completefile, PATH_MAX, "%s/%s", localpath, fn);
|
||||||
rename(output, completefile);
|
rename(output, completefile);
|
||||||
} else if(filedone < 0) {
|
} 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);
|
return(-1);
|
||||||
}
|
}
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
|
121
src/strhash.c
121
src/strhash.c
|
@ -16,7 +16,7 @@
|
||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with evtgen; see the file COPYING. If not, write to
|
along with evtgen; see the file COPYING. If not, write to
|
||||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Copyright (C) 2004 Tommi Rantala <tommi.rantala@cs.helsinki.fi>
|
/* 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 <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
@ -35,62 +35,54 @@
|
||||||
#include "list.h"
|
#include "list.h"
|
||||||
#include "strhash.h"
|
#include "strhash.h"
|
||||||
|
|
||||||
void
|
void strhash_add_list(strhash_t *hash, PMList* list)
|
||||||
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_add(hash, list->data, NULL);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
strhash_t *
|
strhash_t* new_strhash(size_t hsize)
|
||||||
new_strhash(size_t hsize)
|
|
||||||
{
|
{
|
||||||
strhash_t *h;
|
strhash_t *h;
|
||||||
|
|
||||||
MALLOC(h, sizeof (strhash_t));
|
MALLOC(h, sizeof(strhash_t));
|
||||||
h->size = hsize;
|
h->size = hsize;
|
||||||
h->elmts = 0;
|
h->elmts = 0;
|
||||||
h->hash = DEFAULT_STRHASH_FUNCTION;
|
h->hash = DEFAULT_STRHASH_FUNCTION;
|
||||||
MALLOC(h->htable, hsize * sizeof (strhash_elmt_t *));
|
MALLOC(h->htable, hsize * sizeof(strhash_elmt_t *));
|
||||||
memset(h->htable, 0, hsize * sizeof(strhash_elmt_t *));
|
memset(h->htable, 0, hsize * sizeof(strhash_elmt_t *));
|
||||||
|
|
||||||
return (h);
|
return(h);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void clear_strhash(strhash_t *hash)
|
||||||
clear_strhash(strhash_t *hash)
|
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
strhash_elmt_t *tmp;
|
strhash_elmt_t *tmp;
|
||||||
strhash_elmt_t *tmp_next;
|
strhash_elmt_t *tmp_next;
|
||||||
|
|
||||||
for (i = 0; i < hash->size; i++)
|
for(i = 0; i < hash->size; i++) {
|
||||||
{
|
|
||||||
tmp = hash->htable[i];
|
tmp = hash->htable[i];
|
||||||
while (tmp)
|
while(tmp) {
|
||||||
{
|
|
||||||
tmp_next = tmp->next;
|
tmp_next = tmp->next;
|
||||||
free(tmp);
|
free(tmp);
|
||||||
tmp = tmp_next;
|
tmp = tmp_next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
hash->elmts = 0;
|
hash->elmts = 0;
|
||||||
memset(hash->htable, 0, hash->size * sizeof (void *));
|
memset(hash->htable, 0, hash->size * sizeof(void *));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void free_strhash(strhash_t *hash)
|
||||||
void
|
|
||||||
free_strhash(strhash_t *hash)
|
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
strhash_elmt_t *tmp;
|
strhash_elmt_t *tmp;
|
||||||
strhash_elmt_t *tmp_next;
|
strhash_elmt_t *tmp_next;
|
||||||
|
|
||||||
for (i = 0; i < hash->size; i++)
|
for(i = 0; i < hash->size; i++) {
|
||||||
{
|
|
||||||
tmp = hash->htable[i];
|
tmp = hash->htable[i];
|
||||||
while (tmp)
|
while(tmp) {
|
||||||
{
|
|
||||||
tmp_next = tmp->next;
|
tmp_next = tmp->next;
|
||||||
free(tmp);
|
free(tmp);
|
||||||
tmp = tmp_next;
|
tmp = tmp_next;
|
||||||
|
@ -101,13 +93,12 @@ free_strhash(strhash_t *hash)
|
||||||
free(hash);
|
free(hash);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void strhash_add(strhash_t *hash, char *key, char *data)
|
||||||
strhash_add(strhash_t *hash, char *key, char *data)
|
|
||||||
{
|
{
|
||||||
strhash_elmt_t *elmt;
|
strhash_elmt_t *elmt;
|
||||||
unsigned long hcode;
|
unsigned long hcode;
|
||||||
|
|
||||||
MALLOC(elmt, sizeof (strhash_elmt_t));
|
MALLOC(elmt, sizeof(strhash_elmt_t));
|
||||||
elmt->key = key;
|
elmt->key = key;
|
||||||
elmt->data = data;
|
elmt->data = data;
|
||||||
|
|
||||||
|
@ -117,56 +108,72 @@ strhash_add(strhash_t *hash, char *key, char *data)
|
||||||
hash->elmts++;
|
hash->elmts++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 1: Yes, the key exists in the hash table.
|
void strhash_remove(strhash_t *hash, char *key)
|
||||||
* 0: No, its not here.
|
{
|
||||||
*/
|
unsigned long hcode;
|
||||||
|
strhash_elmt_t *elmt;
|
||||||
|
strhash_elmt_t *prev = NULL;
|
||||||
|
|
||||||
int
|
hcode = hash->hash(key) % hash->size;
|
||||||
strhash_isin(strhash_t *hash, char* key)
|
|
||||||
|
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, it's not here.
|
||||||
|
*/
|
||||||
|
int strhash_isin(strhash_t *hash, char* key)
|
||||||
{
|
{
|
||||||
strhash_elmt_t *elmt;
|
strhash_elmt_t *elmt;
|
||||||
|
|
||||||
elmt = hash->htable[hash->hash(key) % hash->size];
|
elmt = hash->htable[hash->hash(key) % hash->size];
|
||||||
for (; elmt; elmt = elmt->next)
|
for(; elmt; elmt = elmt->next) {
|
||||||
{
|
if(!strcmp(key, elmt->key)) {
|
||||||
if (!strcmp(key, elmt->key))
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
char*
|
char* strhash_get(strhash_t *hash, char* key)
|
||||||
strhash_get(strhash_t *hash, char* key)
|
|
||||||
{
|
{
|
||||||
strhash_elmt_t *elmt;
|
strhash_elmt_t *elmt;
|
||||||
|
|
||||||
elmt = hash->htable[hash->hash(key) % hash->size];
|
elmt = hash->htable[hash->hash(key) % hash->size];
|
||||||
for (; elmt; elmt = elmt->next)
|
for(; elmt; elmt = elmt->next) {
|
||||||
{
|
if(!strcmp(key, elmt->key)) {
|
||||||
if (!strcmp(key, elmt->key))
|
|
||||||
return elmt->data;
|
return elmt->data;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** fast hash function samples
|
** fast hash function samples
|
||||||
*/
|
*/
|
||||||
|
unsigned long strhash_pjw(char *key)
|
||||||
unsigned long
|
|
||||||
strhash_pjw(char *key)
|
|
||||||
{
|
{
|
||||||
unsigned long h;
|
unsigned long h;
|
||||||
unsigned long g;
|
unsigned long g;
|
||||||
|
|
||||||
h = 0;
|
h = 0;
|
||||||
while (*key)
|
while(*key) {
|
||||||
{
|
|
||||||
h = (h << 4) + *key++;
|
h = (h << 4) + *key++;
|
||||||
if ((g = h & 0xF0000000U) != 0)
|
if((g = h & 0xF0000000U) != 0) {
|
||||||
{
|
|
||||||
h = h ^ (g >> 24);
|
h = h ^ (g >> 24);
|
||||||
h = h ^ g;
|
h = h ^ g;
|
||||||
}
|
}
|
||||||
|
@ -175,21 +182,21 @@ strhash_pjw(char *key)
|
||||||
return (h);
|
return (h);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int strhash_collide_count(strhash_t *hash)
|
||||||
strhash_collide_count(strhash_t *hash)
|
|
||||||
{
|
{
|
||||||
int count;
|
int count;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
count = 0;
|
count = 0;
|
||||||
for (i = 0; i < hash->size; i++)
|
for(i = 0; i < hash->size; i++) {
|
||||||
{
|
|
||||||
strhash_elmt_t *tmp;
|
strhash_elmt_t *tmp;
|
||||||
|
|
||||||
for (tmp = hash->htable[i]; tmp; tmp = tmp->next)
|
for(tmp = hash->htable[i]; tmp; tmp = tmp->next) {
|
||||||
if (tmp->next)
|
if(tmp->next) {
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return (count);
|
return(count);
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,6 +55,7 @@ void strhash_add_list(strhash_t *hash, PMList* list);
|
||||||
strhash_t *new_strhash(size_t hsize);
|
strhash_t *new_strhash(size_t hsize);
|
||||||
void free_strhash(strhash_t *hash);
|
void free_strhash(strhash_t *hash);
|
||||||
void clear_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);
|
void strhash_add(strhash_t *hash, char *key, char *data);
|
||||||
int strhash_isin(strhash_t *hash, char* key);
|
int strhash_isin(strhash_t *hash, char* key);
|
||||||
char* strhash_get(strhash_t *hash, char* key);
|
char* strhash_get(strhash_t *hash, char* key);
|
||||||
|
|
Loading…
Add table
Reference in a new issue