Compare commits

...

10 commits

Author SHA1 Message Date
Judd Vinet
ec1fc664c9 Imported from pacman-2.9.8.tar.gz 2006-02-02 23:39:53 +00:00
Judd Vinet
1bcc87c3fe Imported from pacman-2.9.7.tar.gz 2005-09-16 18:22:02 +00:00
Judd Vinet
de98f7004e Imported from pacman-2.9.7-TEST3.tar.gz 2005-09-11 23:18:42 +00:00
Judd Vinet
3ba0d67cb1 Imported from pacman-2.9.7-TEST2.tar.gz 2005-09-07 07:03:50 +00:00
Judd Vinet
08962d40c0 Imported from pacman-2.9.7-TEST.tar.gz 2005-08-19 22:41:20 +00:00
Judd Vinet
d05f0047a0 Imported from pacman-2.9.6.tar.gz 2005-06-10 21:31:25 +00:00
Judd Vinet
d48cc3bf5d Imported from pacman-2.9.5.tar.gz 2005-01-11 23:14:16 +00:00
Judd Vinet
ad39cd7bd6 Imported from pacman-2.9.4.tar.gz 2004-12-20 01:37:08 +00:00
Judd Vinet
f6b8ed22f4 Imported from pacman-2.9.3.tar.gz 2004-12-19 03:37:00 +00:00
Judd Vinet
4795965caf Imported from pacman-2.9.2.tar.gz 2004-09-25 18:03:03 +00:00
33 changed files with 2111 additions and 519 deletions

View file

@ -1,5 +1,61 @@
VERSION DESCRIPTION VERSION DESCRIPTION
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
2.9.8 - Changed behaviour with original=X,current=Y,new=Z scenario
- keep old in place, install new as .pacnew
- Search package provides when finding matching targets with -S
- Frugalware: added -Qm option to find foreign packages
- Frugalware: added DistCC support to makepkg
- bugfix: before searching databases for a dependency, make sure
one of the packages in the final list doesn't already provide
that dependency
- fix for segfaults that occurred when propagating requiredby
fields to replaced packages where one package depended on
another replaced package
- a better fix for pacman-optimize integrity checks
- fix for regex searches with -Ss (Miklos Vajna)
- added a --noprogressbar for scripts to use
2.9.7 - fixed the dupe listings of packages when dealing w/ groups
- patches from Miklos Vajna:
- add regexp search support for -Qs and -Ss
- fixed md5sums on x86_64
- add --sudosync to makepkg
- show syntax help if an invalid option is used
- added makepkg option to disable ccache support
- changed license field to operate as an array, not a string
- added more logic for file conflict checks - if one target
is a file and the other is a directory, then it's a conflict
- fixed the integrity check in pacman-optimize
- reverted NoUpgrade to old behaviour and instead, added the
NoExtract directive to pacman.conf, which prevents a file
from ever being extracted on to the system
eg, NoExtract = home/httpd/html/index.html
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 ccache 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
- patch from Tommi Rantala to fix trim() behaviour with
empty or whitespace-only strings
- fixed removal order when using -Rc or -Rs
2.9.4 - fixed a bug that was introduced from another bugfix :-/
2.9.3 - fixed a couple manpage typos
- added --ignore to -S operations, works just like IgnorePkg
- respect IgnorePkg list when pulling in dependencies
- numerous memleak fixes
- some code changes to improve customizability/branding
- Makefile fix for nonstandard lib search paths (Kevin Piche)
- fixed the leftover directories in /tmp
- speed improvement patches from Tommi Rantala
2.9.2 - bugfix for 2.9.1
2.9.1 - --refresh now only downloads fresh packages lists if they've 2.9.1 - --refresh now only downloads fresh packages lists if they've
been updated (currently only works with FTP) been updated (currently only works with FTP)
2.9 - Improved -Rs functionality -- pacman now tracks why a package 2.9 - Improved -Rs functionality -- pacman now tracks why a package

View file

@ -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.1 PACVER = 2.9.8
TOPDIR = @srcdir@ TOPDIR = @srcdir@
SRCDIR = $(TOPDIR)/src/ SRCDIR = $(TOPDIR)/src/
@ -55,6 +55,7 @@ SRCS = $(SRCDIR)pacman.c \
$(SRCDIR)pacsync.c \ $(SRCDIR)pacsync.c \
$(SRCDIR)md5.c \ $(SRCDIR)md5.c \
$(SRCDIR)md5driver.c \ $(SRCDIR)md5driver.c \
$(SRCDIR)strhash.c \
$(SRCDIR)vercmp.c \ $(SRCDIR)vercmp.c \
$(SRCDIR)rpmvercmp.c $(SRCDIR)rpmvercmp.c
@ -66,6 +67,7 @@ OBJECTS = $(OBJDIR)pacman.o \
$(OBJDIR)pacsync.o \ $(OBJDIR)pacsync.o \
$(OBJDIR)md5.o \ $(OBJDIR)md5.o \
$(OBJDIR)md5driver.o \ $(OBJDIR)md5driver.o \
$(OBJDIR)strhash.o \
$(OBJDIR)rpmvercmp.o $(OBJDIR)rpmvercmp.o
all: libftp.a pacman vercmp convertdb man all: libftp.a pacman vercmp convertdb man
@ -78,7 +80,7 @@ vercmp: $(OBJDIR)vercmp.o $(OBJDIR)rpmvercmp.o
$(CXX) $(OBJDIR)vercmp.o $(OBJDIR)rpmvercmp.o $(CXXFLAGS) -o $@ $(CXX) $(OBJDIR)vercmp.o $(OBJDIR)rpmvercmp.o $(CXXFLAGS) -o $@
convertdb: $(OBJDIR)convertdb.o $(OBJDIR)list.o $(OBJDIR)util.o convertdb: $(OBJDIR)convertdb.o $(OBJDIR)list.o $(OBJDIR)util.o
$(CXX) $(OBJDIR)convertdb.o $(OBJDIR)list.o $(OBJDIR)util.o $(CXXFLAGS) -lz -ltar -o $@ $(CXX) $(OBJDIR)convertdb.o $(OBJDIR)list.o $(OBJDIR)util.o $(LDFLAGS) -o $@
.c.o: $(SRCS) .c.o: $(SRCS)
$(CXX) $(CXXFLAGS) -o $@ -c $< $(CXX) $(CXXFLAGS) -o $@ -c $<
@ -104,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

View file

@ -1,4 +1,4 @@
.TH makepkg 8 "August 3, 2004" "makepkg #VERSION#" "" .TH makepkg 8 "January 30, 2006" "makepkg #VERSION#" ""
.SH NAME .SH NAME
makepkg \- package build utility makepkg \- package build utility
.SH SYNOPSIS .SH SYNOPSIS
@ -236,9 +236,26 @@ This is the release number specific to Arch Linux packages.
This should be a brief description of the package and its functionality. This should be a brief description of the package and its functionality.
.TP .TP
.B force .B options
This is used to force the package to be upgraded by \fB--sysupgrade\fP, even This array allows you to override some of makepkg's default behaviour
when building packages. To set an option, just include the option name
in the \fBoptions\fP array.
.TP
.RS
\fIAvailable Options:\fP
.RS
.TP
.B FORCE
force the package to be upgraded by \fB--sysupgrade\fP, even
if its an older version. if its an older version.
.TP
.B KEEPDOCS
do not remove /usr/share/doc and /usr/share/info directories.
.TP
.B NOSTRIP
do not strip debugging symbols from binaries and libraries.
.RE
.RE
.TP .TP
.B url .B url
@ -247,8 +264,17 @@ being packaged. This is typically the project's website.
.TP .TP
.B license .B license
Sets the license type (eg, "GPL", "BSD", "NON-FREE"). (\fBNote\fP: This This field specifies the license(s) that apply to the package. Commonly-used
option is still in development and may change in the future) licenses are typically found in \fI/usr/share/licenses/common\fP. If you
see the package's license there, simply reference it in the license field
(eg, \fBlicense="GPL"\fP). If the package provides a license not found in
\fI/usr/share/licenses/common\fP, then you should include the license in
the package itself and set \fBlicense="custom"\fP or \fBlicense="custom:LicenseName"\fP.
The license itself should be placed in a directory called
\fI$startdir/pkg/usr/share/licenses/$pkgname\fP.
.TP
.RE
If multiple licenses are applied, use the array form: \fBlicenses=('GPL' 'FDL')\fP
.TP .TP
.B install .B install
@ -271,7 +297,7 @@ If this field is present, it should contain an MD5 hash for every source file
specified in the \fIsource\fP array (in the same order). makepkg will use specified in the \fIsource\fP array (in the same order). makepkg will use
this to verify source file integrity during subsequent builds. To easily this to verify source file integrity during subsequent builds. To easily
generate md5sums, first build using the PKGBUILD then run generate md5sums, first build using the PKGBUILD then run
\fBmakepkg -g >>PKGBILD\fP. Then you can edit the PKGBUILD and move the \fBmakepkg -g >>PKGBUILD\fP. Then you can edit the PKGBUILD and move the
\fImd5sums\fP line from the bottom to an appropriate location. \fImd5sums\fP line from the bottom to an appropriate location.
.TP .TP
@ -331,6 +357,9 @@ $ABSROOT (set in your /etc/makepkg.conf). If it finds them it will
run another copy of makepkg to build and install the missing dependencies. run another copy of makepkg to build and install the missing dependencies.
The child makepkg calls will be made with the \fB-b\fP and \fB-i\fP options. The child makepkg calls will be made with the \fB-b\fP and \fB-i\fP options.
.TP .TP
.B "\-B, \-\-noccache"
Do not use ccache during build.
.TP
.B "\-c, \-\-clean" .B "\-c, \-\-clean"
Clean up leftover work files/directories after a successful build. Clean up leftover work files/directories after a successful build.
.TP .TP
@ -342,6 +371,11 @@ Do not perform any dependency checks. This will let you override/ignore any
dependencies required. There's a good chance this option will break the build dependencies required. There's a good chance this option will break the build
process if all of the dependencies aren't installed. process if all of the dependencies aren't installed.
.TP .TP
.B "\-e, \-\-noextract"
Do not extract source files. Instead, use whatever already exists in the
src/ directory. This is handy if you want to go into src and manually
patch/tweak code, then make a package out of the result.
.TP
.B "\-f, \-\-force" .B "\-f, \-\-force"
\fBmakepkg\fP will not build a package if a \fIpkgname-pkgver-pkgrel.pkg.tar.gz\fP \fBmakepkg\fP will not build a package if a \fIpkgname-pkgver-pkgrel.pkg.tar.gz\fP
file already exists in the build directory. You can override this behaviour with file already exists in the build directory. You can override this behaviour with
@ -384,9 +418,23 @@ or run-time dependencies, it will run pacman to try and resolve them. If succes
pacman will download the missing packages from a package repository and pacman will download the missing packages from a package repository and
install them for you. install them for you.
.TP .TP
.B "\-S, \-\-sudosync"
Install missing dependencies using pacman and sudo. This is the same as \fB-s\fP
except that makepkg will call pacman with sudo. This means you don't have to
build as root to use dependency auto-resolution.
.TP
.B "\-w <destdir>" .B "\-w <destdir>"
Write the resulting package file to the directory \fI<destdir>\fP instead of the Write the resulting package file to the directory \fI<destdir>\fP instead of the
current working directory. current working directory.
.TP
.B "\-\-noconfirm"
When calling pacman to resolve dependencies or conflicts, makepkg can pass
the \fI--noconfirm\fP option to it so it does not wait for any user
input before proceeding with operations.
.TP
.B "\-\-noprogressbar"
When calling pacman, makepkg can pass the \fI--noprogressbar\fP option to it.
This is useful if one is directing makepkg's output to a non-terminal (ie, a file).
.SH CONFIGURATION .SH CONFIGURATION
Configuration options are stored in \fI/etc/makepkg.conf\fP. This file is parsed Configuration options are stored in \fI/etc/makepkg.conf\fP. This file is parsed

View file

@ -1,4 +1,4 @@
.TH pacman 8 "September 17, 2004" "pacman #VERSION#" "" .TH pacman 8 "January 21, 2006" "pacman #VERSION#" ""
.SH NAME .SH NAME
pacman \- package manager utility pacman \- package manager utility
.SH SYNOPSIS .SH SYNOPSIS
@ -60,7 +60,7 @@ installed and there are no package conflicts in the system. This
switch disables these checks. switch disables these checks.
.TP .TP
.B "\-f, \-\-force" .B "\-f, \-\-force"
Bypass file conflict checks,, overwriting conflicting files. If the Bypass file conflict checks, overwriting conflicting files. If the
package that is about to be installed contains files that are already package that is about to be installed contains files that are already
installed, this option will cause all those files to be overwritten. installed, this option will cause all those files to be overwritten.
This option should be used with care, ideally not at all. This option should be used with care, ideally not at all.
@ -81,8 +81,12 @@ 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.
.TP
.B "\-\-noprogressbar"
Do not show a progress bar when downloading files. This can be useful for
scripts that call pacman and capture the output.
.SH SYNC OPTIONS .SH SYNC OPTIONS
.TP .TP
.B "\-c, \-\-clean" .B "\-c, \-\-clean"
@ -106,13 +110,13 @@ List all files in the specified repositories. Multiple repositories can
be specified on the command line. be specified on the command line.
.TP .TP
.B "\-p, \-\-print-uris" .B "\-p, \-\-print-uris"
Print out URIs for each specified package and its dependencies. These Print out URIs for each package that will be installed, including any
can be piped to a file and downloaded at a later time, using a program dependencies that have yet to be installed. These can be piped to a
like wget. file and downloaded at a later time, using a program like wget.
.TP .TP
.B "\-s, \-\-search <string>" .B "\-s, \-\-search <regexp>"
This will search each package in the package list for names or descriptions This will search each package in the package list for names or descriptions
that contains <string>. that matches <regexp>.
.TP .TP
.B "\-u, \-\-sysupgrade" .B "\-u, \-\-sysupgrade"
Upgrades all packages that are out of date. pacman will examine every Upgrades all packages that are out of date. pacman will examine every
@ -129,6 +133,11 @@ Retrieve all packages from the server, but do not install/upgrade anything.
Download a fresh copy of the master package list from the ftp server Download a fresh copy of the master package list from the ftp server
defined in \fI/etc/pacman.conf\fP. This should typically be used each defined in \fI/etc/pacman.conf\fP. This should typically be used each
time you use \fB--sysupgrade\fP. time you use \fB--sysupgrade\fP.
.TP
.B "\-\-ignore <pkg>"
This option functions exactly the same as the \fBIgnorePkg\fP configuration
directive. Sometimes it can be handy to skip some package updates without
having to edit \fIpacman.conf\fP each time.
.SH REMOVE OPTIONS .SH REMOVE OPTIONS
.TP .TP
.B "\-c, \-\-cascade" .B "\-c, \-\-cascade"
@ -147,9 +156,9 @@ removed.
.TP .TP
.B "\-s, \-\-recursive" .B "\-s, \-\-recursive"
For each target specified, remove it and all its dependencies, provided For each target specified, remove it and all its dependencies, provided
that (A) they are not required by other packages; and (B) they were that (A) they are not required by other packages; and (B) they were not
explicitly installed by the user and not pulled in as a dependency for explicitly installed by the user.
other packages. This option is analagous to a backwards --sync operation. This option is analagous to a backwards --sync operation.
.SH QUERY OPTIONS .SH QUERY OPTIONS
.TP .TP
.B "\-e, \-\-orphans" .B "\-e, \-\-orphans"
@ -169,6 +178,10 @@ option then the .PKGINFO file will be printed.
List all files owned by <package>. Multiple packages can be specified on List all files owned by <package>. Multiple packages can be specified on
the command line. the command line.
.TP .TP
.B "\-m, \-\-foreign"
List all packages that were not found in the sync database(s). Typically these
are packages that were downloaded manually and installed with --add.
.TP
.B "\-o, \-\-owns <file>" .B "\-o, \-\-owns <file>"
Search for the package that owns <file>. Search for the package that owns <file>.
.TP .TP
@ -177,9 +190,9 @@ Tells pacman that the package supplied on the command line is a
file, not an entry in the database. Pacman will decompress the file, not an entry in the database. Pacman will decompress the
file and query it. This is useful with \fB--info\fP and \fB--list\fP. file and query it. This is useful with \fB--info\fP and \fB--list\fP.
.TP .TP
.B "\-s, \-\-search <string>" .B "\-s, \-\-search <regexp>"
This will search each locally-installed package for names or descriptions This will search each locally-installed package for names or descriptions
that contains <string>. that matches <regexp>.
.SH HANDLING CONFIG FILES .SH HANDLING CONFIG FILES
pacman uses the same logic as rpm to determine action against files pacman uses the same logic as rpm to determine action against files
that are designated to be backed up. During an upgrade, it uses 3 that are designated to be backed up. During an upgrade, it uses 3
@ -205,9 +218,9 @@ original=\fBX\fP, current=\fBY\fP, new=\fBY\fP
The new one is identical to the current one. Win win. Install the new file. The new one is identical to the current one. Win win. Install the new file.
.TP .TP
original=\fBX\fP, current=\fBY\fP, new=\fBZ\fP original=\fBX\fP, current=\fBY\fP, new=\fBZ\fP
All three files are different. So we install the new file, but back up the All three files are different, so we install the new file with a .pacnew
old one to a .pacsave extension. This way the user can move the old configuration extension and warn the user, so she can manually move the file into place
file back into place if he wishes. after making any necessary customizations.
.SH CONFIGURATION .SH CONFIGURATION
pacman will attempt to read \fI/etc/pacman.conf\fP each time it is invoked. This pacman will attempt to read \fI/etc/pacman.conf\fP each time it is invoked. This
configuration file is divided into sections or \fIrepositories\fP. Each section configuration file is divided into sections or \fIrepositories\fP. Each section
@ -267,6 +280,13 @@ Disables passive ftp connections when downloading packages. (aka Active Mode)
All files listed with a \fBNoUpgrade\fP directive will never be touched during a package All files listed with a \fBNoUpgrade\fP directive will never be touched during a package
install/upgrade. \fINote:\fP do not include the leading slash when specifying files. install/upgrade. \fINote:\fP do not include the leading slash when specifying files.
.TP .TP
.B "NoExtract = <file> [file] ..."
All files listed with a \fBNoExtract\fP directive will never be extracted from
a package into the filesystem. This can be useful when you don't want part of
a package to be installed. For example, if your httpd root uses an index.php,
then you would not want the index.html file to be extracted from the apache
package.
.TP
.B "UseSyslog" .B "UseSyslog"
Log action messages through syslog(). This will insert pacman log entries into your Log action messages through syslog(). This will insert pacman log entries into your
/var/log/messages or equivalent. /var/log/messages or equivalent.

View file

@ -2,35 +2,58 @@
# /etc/makepkg.conf # /etc/makepkg.conf
# #
# The FTP/HTTP download utility that makepkg should use to acquire sources #########################################################################
export FTPAGENT="/usr/bin/wget --continue --passive-ftp --tries=3 --waitretry=3" # SOURCE ACQUISITION
#########################################################################
#
#-- The FTP/HTTP download utility that makepkg should use to acquire sources
export FTPAGENT="/usr/bin/wget --continue --passive-ftp --tries=3 --waitretry=3 --no-check-certificate"
#export FTPAGENT="/usr/bin/snarf" #export FTPAGENT="/usr/bin/snarf"
#export FTPAGENT="/usr/bin/lftpget -c" #export FTPAGENT="/usr/bin/lftpget -c"
#########################################################################
# ARCHITECTURE, COMPILE FLAGS
#########################################################################
#
export CARCH="i686" export CARCH="i686"
export CHOST="i686-pc-linux-gnu" export CHOST="i686-pc-linux-gnu"
#-- Exclusive: will only run on i686 or higher (P6, Athlon)
# 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 CFLAGS="-march=i686 -O2 -pipe"
export CXXFLAGS="-march=i686 -O2 -pipe" export CXXFLAGS="-march=i686 -O2 -pipe"
# Pentium Pro/Pentium II/Pentium III+/Pentium 4/Athlon optimized (but binaries #-- Optimized: will run on any x86, but optimized for i686
# will run on any x86 system)
#export CFLAGS="-mcpu=i686 -O2 -pipe" #export CFLAGS="-mcpu=i686 -O2 -pipe"
#export CXXFLAGS="-mcpu=i686 -O2 -pipe" #export CXXFLAGS="-mcpu=i686 -O2 -pipe"
#-- Make Flags: change this for DistCC/SMP systems
#export MAKEFLAGS="-j2"
# SMP Systems #########################################################################
#export MAKEFLAGS="-j 2" # BUILD ENVIRONMENT
#########################################################################
# Enable fakeroot for building packages as a non-root user #
#-- Fakeroot: for building packages as a non-root user
export USE_FAKEROOT="y" export USE_FAKEROOT="y"
#-- DistCC: a distributed C/C++/ObjC compiler (modify MAKEFLAGS too)
export DISTCC="n"
#-- A space-delimited list of hosts running in the DistCC cluster
export DISTCC_HOSTS=""
#-- Colorized output messages
export USE_COLOR="y"
# Enable colorized output messages #########################################################################
export USE_COLOR="n" # GLOBAL PACKAGE OPTIONS
#########################################################################
#
#-- Don't strip symbols from binaries/libraries
#export NOSTRIP="1"
#-- Keep doc and info directories
#export KEEPDOCS="1"
# Specify a fixed directory where all packages will be placed #########################################################################
# PACKAGE OUTPUT
#########################################################################
#
#-- Destination: specify a fixed directory where all packages will be placed
#export PKGDEST=/home/packages #export PKGDEST=/home/packages
#-- Packager: name/email of the person or organization building packages
# If you want your name to show up in the packages you build, set this.
#export PACKAGER="John Doe <john@doe.com>" #export PACKAGER="John Doe <john@doe.com>"

View file

@ -19,10 +19,10 @@
[options] [options]
LogFile = /var/log/pacman.log LogFile = /var/log/pacman.log
NoUpgrade = etc/passwd etc/group etc/shadow etc/sudoers NoUpgrade = etc/passwd etc/group etc/shadow etc/sudoers
NoUpgrade = etc/fstab etc/raidtab etc/ld.so.conf NoUpgrade = etc/fstab etc/raidtab etc/mdadm.conf etc/ld.so.conf
NoUpgrade = etc/rc.conf etc/rc.local NoUpgrade = etc/inittab etc/rc.conf etc/rc.local
NoUpgrade = etc/modprobe.conf etc/modules.conf NoUpgrade = etc/modprobe.conf etc/modules.conf
NoUpgrade = etc/lilo.conf boot/grub/menu.lst NoUpgrade = etc/lilo.conf boot/grub/menu.lst etc/mkinitrd.conf
HoldPkg = pacman glibc HoldPkg = pacman glibc
#XferCommand = /usr/bin/wget --passive-ftp -c -O %o %u #XferCommand = /usr/bin/wget --passive-ftp -c -O %o %u

24
scripts/aurbuild Executable file
View file

@ -0,0 +1,24 @@
#!/bin/bash
die() {
echo $*
exit 1
}
if [ "$1" == "" ]; then
echo "usage: aurbuild <package_name>"
echo
exit 1
fi
pkgname=$1
[ -d $pkgname ] && die "Directory '$pkgname' already exists"
[ -f $pkgname ] && die "File '$pkgname' already exists"
echo "Downloading $pkgname.tar.gz"
wget -q http://aur.archlinux.org/packages/$pkgname/$pkgname.tar.gz || die "Failed to fetch $1.pkg.tar.gz"
tar zxf $pkgname.tar.gz || die "Extraction failed"
rm -f $pkgname.tar.gz
cd $pkgname || die "Failed to cwd"
makepkg

View file

@ -2,7 +2,7 @@
# #
# gensync # gensync
# #
# Copyright (c) 2002-2004 by Judd Vinet <jvinet@zeroflux.org> # Copyright (c) 2002-2006 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.1' myver='2.9.8'
usage() { usage() {
echo "gensync $myver" echo "gensync $myver"
@ -51,6 +51,18 @@ die() {
exit 1 exit 1
} }
check_option() {
local i
for i in ${options[@]}; do
local uc=`echo $i | tr [:lower:] [:upper:]`
local lc=`echo $i | tr [:upper:] [:lower:]`
if [ "$uc" = "$1" -o "$lc" = "$1" ]; then
echo $1
return
fi
done
}
get_md5checksum() get_md5checksum()
{ {
if [ "$pkgdir" != "" ]; then if [ "$pkgdir" != "" ]; then
@ -69,7 +81,7 @@ get_md5checksum()
db_write_entry() db_write_entry()
{ {
unset pkgname pkgver pkgrel pkgdesc force unset pkgname pkgver pkgrel pkgdesc force
unset groups replaces provides depends conflicts unset groups replaces provides depends conflicts options
source $1 || return 1 source $1 || return 1
cd $gstmpdir cd $gstmpdir
mkdir $pkgname-$pkgver-$pkgrel || return 1 mkdir $pkgname-$pkgver-$pkgrel || return 1
@ -107,7 +119,7 @@ db_write_entry()
done done
echo "" >>desc echo "" >>desc
fi fi
if [ "$force" = "y" -o "$force" = "Y" ]; then if [ "$force" = "y" -o "$force" = "Y" -o "`check_option FORCE`" ]; then
echo "%FORCE%" >>desc echo "%FORCE%" >>desc
echo "" >>desc echo "" >>desc
fi fi
@ -134,11 +146,13 @@ db_write_entry()
done done
echo "" >>depends echo "" >>depends
fi fi
# preserve the modification time
touch -r $1 desc depends
} }
if [ $# -lt 2 ]; then if [ $# -lt 2 ]; then
usage usage
exit 0 exit 1
fi fi
if [ "$1" = "-h" -o "$1" = "--help" ]; then if [ "$1" = "-h" -o "$1" = "--help" ]; then
@ -167,12 +181,14 @@ for file in `find $rootdir/* -name PKGBUILD`; do
else else
pkgfile="$destdir/$pkgname-$pkgver-$pkgrel.pkg.tar.gz" pkgfile="$destdir/$pkgname-$pkgver-$pkgrel.pkg.tar.gz"
fi fi
[ -f $pkgfile ] || die "missing package file: $pkgfile" if [ -f $pkgfile ]; then
csize=`du -b $pkgfile | cut -f1` csize=`du -b $pkgfile | cut -f1`
pkgmd5sum=`get_md5checksum $pkgfile` pkgmd5sum=`get_md5checksum $pkgfile`
[ -z $pkgmd5sum ] && die "error generating checksum for $pkgfile" [ -z $pkgmd5sum ] && die "error generating checksum for $pkgfile"
db_write_entry $file db_write_entry $file || die "error writing entry for $file"
[ $? -gt 0 ] && die "error writing entry for $file" else
echo "gensync: missing package: $pkgfile" >&2
fi
done done
echo "gensync: compressing to $destfile..." >&2 echo "gensync: compressing to $destfile..." >&2

View file

@ -2,7 +2,7 @@
# #
# makepkg # makepkg
# #
# Copyright (c) 2002-2004 by Judd Vinet <jvinet@zeroflux.org> # Copyright (c) 2002-2006 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,11 +20,31 @@
# USA. # USA.
# #
myver='2.9.1' myver='2.9.8'
startdir=`pwd` startdir=`pwd`
PKGDEST=$startdir PKGDEST=$startdir
USE_COLOR="n" USE_COLOR="n"
# Options
BUILDSCRIPT="./PKGBUILD"
CLEANUP=0
CLEANCACHE=0
DEP_BIN=0
DEP_SRC=0
DEP_SUDO=0
FORCE=0
GENMD5=0
INSTALL=0
KEEPDOCS=0
NOBUILD=0
NOCCACHE=0
NODEPS=0
NOEXTRACT=0
NOSTRIP=0
RMDEPS=0
PACMAN_OPTS=
# source Arch's abs.conf if it's present # source Arch's abs.conf if it's present
[ -f /etc/abs/abs.conf ] && source /etc/abs/abs.conf [ -f /etc/abs/abs.conf ] && source /etc/abs/abs.conf
@ -72,11 +92,25 @@ strip_url() {
echo $1 | sed 's|^.*://.*/||g' echo $1 | sed 's|^.*://.*/||g'
} }
check_option() {
local i
for i in ${options[@]}; do
local uc=`echo $i | tr [:lower:] [:upper:]`
local lc=`echo $i | tr [:upper:] [:lower:]`
if [ "$uc" = "$1" -o "$lc" = "$1" ]; then
echo $1
return
fi
done
}
checkdeps() { checkdeps() {
local missdep="" local missdep=""
local deplist="" local deplist=""
missdep=`pacman -T $*` [ $# -gt 0 ] || return
missdep=`pacman $PACMAN_OPTS -T $*`
ret=$? ret=$?
if [ "$ret" != "0" ]; then if [ "$ret" != "0" ]; then
if [ "$ret" = "127" ]; then if [ "$ret" = "127" ]; then
@ -108,7 +142,7 @@ handledeps() {
local missingdeps=0 local missingdeps=0
local deplist="$*" local deplist="$*"
local haveperm=0 local haveperm=0
if [ "`id -u`" = "0" -a "$INFAKEROOT" != "1" ]; then if [ \( "`id -u`" = "0" -a "$INFAKEROOT" != "1" \) -o "$DEP_SUDO" = 1 ]; then
haveperm=1 haveperm=1
fi fi
@ -116,7 +150,26 @@ handledeps() {
if [ "$DEP_BIN" = "1" ]; then if [ "$DEP_BIN" = "1" ]; then
# install missing deps from binary packages (using pacman -S) # install missing deps from binary packages (using pacman -S)
msg "Installing missing dependencies..." msg "Installing missing dependencies..."
pacman -D $deplist pacman $PACMAN_OPTS -D $deplist
if [ "$?" = "127" ]; then
error "Failed to install missing dependencies."
exit 1
fi
# TODO: check deps again to make sure they were resolved
elif [ "$DEP_SUDO" = "1" ]; then
# install missing deps from binary packages (using pacman -S and sudo)
msg "Installing missing dependencies..."
if [ "$INFAKEROOT" = "1" ]; then
# kinda hacky, but we need to make pacman think that we're NOT
# in fakeroot so it will go ahead and install the dependencies.
FAKEROOTKEY2=$FAKEROOTKEY
unset FAKEROOTKEY
fi
sudo pacman $PACMAN_OPTS -D $deplist
if [ "$INFAKEROOT" = "1" ]; then
export FAKEROOTKEY=$FAKEROOTKEY2
unset FAKEROOTKEY2
fi
if [ "$?" = "127" ]; then if [ "$?" = "127" ]; then
error "Failed to install missing dependencies." error "Failed to install missing dependencies."
exit 1 exit 1
@ -163,8 +216,8 @@ handledeps() {
fi fi
elif [ "$deplist" != "" -a $haveperm -eq 0 ]; then elif [ "$deplist" != "" -a $haveperm -eq 0 ]; then
if [ "$DEP_SRC" = "1" -o "$DEP_BIN" = "1" ]; then if [ "$DEP_SRC" = "1" -o "$DEP_BIN" = "1" ]; then
warning "Cannot auto-install missing dependencies as a normal user!" warning "Cannot auto-install missing dependencies as a normal user without sudo!"
plain "Run makepkg as root to resolve dependencies automatically." plain "Run makepkg as root or with -S to resolve dependencies automatically."
fi fi
missingdeps=1 missingdeps=1
fi fi
@ -173,9 +226,12 @@ handledeps() {
usage() { usage() {
echo "makepkg version $myver" echo "makepkg version $myver"
echo "usage: $0 [options]" echo
echo "options:" echo "Usage: $0 [options]"
echo
echo "Options:"
echo " -b, --builddeps Build missing dependencies from source" echo " -b, --builddeps Build missing dependencies from source"
echo " -B, --noccache Do not use ccache during build"
echo " -c, --clean Clean up work files after build" echo " -c, --clean Clean up work files after build"
echo " -C, --cleancache Clean up source files from the cache" echo " -C, --cleancache Clean up source files from the cache"
echo " -d, --nodeps Skip all dependency checks" echo " -d, --nodeps Skip all dependency checks"
@ -191,37 +247,32 @@ usage() {
echo " -p <buildscript> Use an alternate build script (instead of PKGBUILD)" echo " -p <buildscript> Use an alternate build script (instead of PKGBUILD)"
echo " -r, --rmdeps Remove installed dependencies after a successful build" echo " -r, --rmdeps Remove installed dependencies after a successful build"
echo " -s, --syncdeps Install missing dependencies with pacman" echo " -s, --syncdeps Install missing dependencies with pacman"
echo " -S, --sudosync Install missing dependencies with pacman and sudo"
echo " -w <destdir> Write package to <destdir> instead of the working dir" echo " -w <destdir> Write package to <destdir> instead of the working dir"
echo echo
echo " if -p is not specified, makepkg will look for a PKGBUILD" echo "These options can be passed to pacman:"
echo " file in the current directory." echo
echo " --noconfirm Do not ask for confirmation when resolving dependencies"
echo " --noprogressbar Do not show a progress bar when downloading files"
echo
echo "If -p is not specified, makepkg will look for ./PKGBUILD"
echo echo
} }
# Options
CLEANUP=0
CLEANCACHE=0
INSTALL=0
GENMD5=0
DEP_BIN=0
DEP_SRC=0
NODEPS=0
FORCE=0
NOEXTRACT=0
NOSTRIP=0
NOBUILD=0
RMDEPS=0
BUILDSCRIPT="./PKGBUILD"
ARGLIST=$@ ARGLIST=$@
while [ "$#" -ne "0" ]; do while [ "$#" -ne "0" ]; do
case $1 in case $1 in
# pacman
--noconfirm) PACMAN_OPTS="$PACMAN_OPTS --noconfirm" ;;
--noprogressbar) PACMAN_OPTS="$PACMAN_OPTS --noprogressbar" ;;
# makepkg
--clean) CLEANUP=1 ;; --clean) CLEANUP=1 ;;
--cleancache) CLEANCACHE=1 ;; --cleancache) CLEANCACHE=1 ;;
--syncdeps) DEP_BIN=1 ;; --syncdeps) DEP_BIN=1 ;;
--sudosync) DEP_SUDO=1 ;;
--builddeps) DEP_SRC=1 ;; --builddeps) DEP_SRC=1 ;;
--noccache) NOCCACHE=1 ;;
--nodeps) NODEPS=1 ;; --nodeps) NODEPS=1 ;;
--noextract) NOEXTRACT=1 ;; --noextract) NOEXTRACT=1 ;;
--install) INSTALL=1 ;; --install) INSTALL=1 ;;
@ -240,11 +291,12 @@ while [ "$#" -ne "0" ]; do
exit 1 exit 1
;; ;;
-*) -*)
while getopts "cCsbdehifgj:mnorp:w:-" opt; do while getopts "bBcCdefghij:mnop:rsSw:-" opt; do
case $opt in case $opt in
b) DEP_SRC=1 ;;
B) NOCCACHE=1 ;;
c) CLEANUP=1 ;; c) CLEANUP=1 ;;
C) CLEANCACHE=1 ;; C) CLEANCACHE=1 ;;
b) DEP_SRC=1 ;;
d) NODEPS=1 ;; d) NODEPS=1 ;;
e) NOEXTRACT=1 ;; e) NOEXTRACT=1 ;;
f) FORCE=1 ;; f) FORCE=1 ;;
@ -261,6 +313,7 @@ while [ "$#" -ne "0" ]; do
p) BUILDSCRIPT=$OPTARG ;; p) BUILDSCRIPT=$OPTARG ;;
r) RMDEPS=1 ;; r) RMDEPS=1 ;;
s) DEP_BIN=1 ;; s) DEP_BIN=1 ;;
S) DEP_SUDO=1 ;;
w) PKGDEST=$OPTARG ;; w) PKGDEST=$OPTARG ;;
-) -)
OPTIND=0 OPTIND=0
@ -280,6 +333,12 @@ while [ "$#" -ne "0" ]; do
shift shift
done done
# check for sudo
if [ "$DEP_SUDO" = "1" -a ! "`type -p sudo`" ]; then
error "Cannot find the sudo binary! Is sudo installed?"
exit 1
fi
# convert a (possibly) relative path to absolute # convert a (possibly) relative path to absolute
cd $PKGDEST 2>/dev/null cd $PKGDEST 2>/dev/null
if [ $? -ne 0 ]; then if [ $? -ne 0 ]; then
@ -302,6 +361,9 @@ fi
unset pkgname pkgver pkgrel pkgdesc url license groups provides md5sums force unset pkgname pkgver pkgrel pkgdesc url license groups provides md5sums force
unset replaces depends conflicts backup source install build makedepends unset replaces depends conflicts backup source install build makedepends
unset options
# some applications (eg, blackbox) will not build with some languages
unset LC_ALL LANG
umask 0022 umask 0022
if [ ! -f $BUILDSCRIPT ]; then if [ ! -f $BUILDSCRIPT ]; then
@ -320,11 +382,16 @@ if [ `echo $pkgrel | grep '-'` ]; then
error "pkgrel is not allowed to contain hyphens." error "pkgrel is not allowed to contain hyphens."
exit 1 exit 1
fi fi
if [ "$install" -a ! -f "$install" ]; then
error "install scriptlet ($install) does not exist."
exit 1
fi
if [ -f $PKGDEST/${pkgname}-${pkgver}-${pkgrel}.pkg.tar.gz -a "$FORCE" = "0" -a "$GENMD5" = "0" ]; then if [ -f $PKGDEST/${pkgname}-${pkgver}-${pkgrel}.pkg.tar.gz -a "$FORCE" = "0" -a "$GENMD5" = "0" ]; then
if [ "$INSTALL" = "1" ]; then if [ "$INSTALL" = "1" ]; then
warning "a package has already been built, installing existing package." warning "a package has already been built, installing existing package."
pacman --upgrade $PKGDEST/${pkgname}-${pkgver}-${pkgrel}.pkg.tar.gz echo pacman $PACMAN_OPTS -U $PKGDEST/${pkgname}-${pkgver}-${pkgrel}.pkg.tar.gz
pacman $PACMAN_OPTS -U $PKGDEST/${pkgname}-${pkgver}-${pkgrel}.pkg.tar.gz
exit $? exit $?
else else
error "a package has already been built. (use -f to overwrite)" error "a package has already been built. (use -f to overwrite)"
@ -357,7 +424,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
@ -463,16 +530,18 @@ if [ "$GENMD5" = "0" ]; then
# extract sources # extract sources
msg "Extracting Sources..." msg "Extracting Sources..."
for netfile in ${source[@]}; do for netfile in ${source[@]}; do
unziphack=0
file=`strip_url $netfile` file=`strip_url $netfile`
unset cmd unset cmd
case $file in case $file in
*.tar.gz|*.tar.Z|*.tgz) *.tar.gz|*.tar.Z|*.tgz)
cmd="tar --use-compress-program=gzip -xf $file" ;; cmd="tar --use-compress-program=gzip -xf $file" ;;
*.tar.bz2) *.tar.bz2|*.tbz2)
cmd="tar --use-compress-program=bzip2 -xf $file" ;; cmd="tar --use-compress-program=bzip2 -xf $file" ;;
*.tar) *.tar)
cmd="tar -xf $file" ;; cmd="tar -xf $file" ;;
*.zip) *.zip)
unziphack=1
cmd="unzip -qqo $file" ;; cmd="unzip -qqo $file" ;;
*.gz) *.gz)
cmd="gunzip $file" ;; cmd="gunzip $file" ;;
@ -483,9 +552,12 @@ if [ "$GENMD5" = "0" ]; then
msg " $cmd" msg " $cmd"
$cmd $cmd
if [ $? -ne 0 ]; then if [ $? -ne 0 ]; then
error "Failed to extract $file" # unzip will return a 1 as a warning, it is not an error
msg "Aborting..." if [ "$unziphack" != "1" -o $? -ne 1 ]; then
exit 1 error "Failed to extract $file"
msg "Aborting..."
exit 1
fi
fi fi
fi fi
done done
@ -529,7 +601,6 @@ else
exit 0 exit 0
fi fi
if [ "`id -u`" = "0" ]; then if [ "`id -u`" = "0" ]; then
# chown all source files to root.root # chown all source files to root.root
chown -R root.root $startdir/src chown -R root.root $startdir/src
@ -547,6 +618,20 @@ if [ "$NOBUILD" = "1" ]; then
exit 0 exit 0
fi fi
# use distcc if requested
if [ "$DISTCC" = "y" ]; then
[ -d /usr/lib/distcc/bin ] && export PATH=/usr/lib/distcc/bin:$PATH
if [ "$INCHROOT" = "1" ]; then
[ -d /var/tmp/fst/.distcc ] || mkdir /var/tmp/fst/.distcc
export DISTCC_DIR=/var/tmp/fst/.distcc
fi
fi
# use ccache if it's available
if [ "$NOCCACHE" = "0" ]; then
[ -d /usr/lib/ccache/bin ] && export PATH=/usr/lib/ccache/bin:$PATH
fi
# build # build
msg "Starting build()..." msg "Starting build()..."
build 2>&1 build 2>&1
@ -555,10 +640,14 @@ if [ $? -gt 0 ]; then
exit 2 exit 2
fi fi
# remove info/doc files if [ ! "`check_option KEEPDOCS`" -a "$KEEPDOCS" = "0" ]; then
cd $startdir # remove info/doc files
rm -rf pkg/usr/info pkg/usr/share/info msg "Removing info/doc files..."
rm -rf pkg/usr/doc pkg/usr/share/doc cd $startdir
rm -rf pkg/usr/info pkg/usr/share/info
rm -rf pkg/usr/doc pkg/usr/share/doc
rm -rf pkg/{usr,opt/gnome}/share/gtk-doc
fi
# move /usr/share/man files to /usr/man # move /usr/share/man files to /usr/man
if [ -d pkg/usr/share/man ]; then if [ -d pkg/usr/share/man ]; then
@ -593,7 +682,7 @@ done
cd $startdir cd $startdir
# strip binaries # strip binaries
if [ "$NOSTRIP" = "0" ]; then if [ ! "`check_option NOSTRIP`" -a "$NOSTRIP" = "0" ]; then
msg "Stripping debugging symbols from libraries..." msg "Stripping debugging symbols from libraries..."
find pkg/{,usr,usr/local,opt/*}/lib -type f -not -name "*.dll" -not -name "*.exe" \ find pkg/{,usr,usr/local,opt/*}/lib -type f -not -name "*.dll" -not -name "*.exe" \
-exec /usr/bin/strip --strip-debug '{}' \; 2>&1 \ -exec /usr/bin/strip --strip-debug '{}' \; 2>&1 \
@ -604,6 +693,18 @@ if [ "$NOSTRIP" = "0" ]; then
| grep -v "No such file" | grep -v "format not recognized" | grep -v "No such file" | grep -v "format not recognized"
fi fi
# remove libtool (.la) files
if [ "`check_option NOLIBTOOL`" ]; then
msg "Removing libtool .la files..."
find pkg -type f -name "*.la" -exec rm -f -- '{}' \;
fi
# remove empty directories
if [ "`check_option NOEMPTYDIRS`" ]; then
msg "Removing empty directories..."
find pkg -mindepth 1 -type d -empty -exec rmdir {} \;
fi
# get some package meta info # get some package meta info
builddate=`LC_ALL= ; LANG= ; date -u "+%a %b %e %H:%M:%S %Y"` builddate=`LC_ALL= ; LANG= ; date -u "+%a %b %e %H:%M:%S %Y"`
if [ "$PACKAGER" != "" ]; then if [ "$PACKAGER" != "" ]; then
@ -623,7 +724,6 @@ echo "pkgname = $pkgname" >>.PKGINFO
echo "pkgver = $pkgver-$pkgrel" >>.PKGINFO echo "pkgver = $pkgver-$pkgrel" >>.PKGINFO
echo "pkgdesc = $pkgdesc" >>.PKGINFO echo "pkgdesc = $pkgdesc" >>.PKGINFO
echo "url = $url" >>.PKGINFO echo "url = $url" >>.PKGINFO
echo "license = $license" >>.PKGINFO
echo "builddate = $builddate" >>.PKGINFO echo "builddate = $builddate" >>.PKGINFO
echo "packager = $packager" >>.PKGINFO echo "packager = $packager" >>.PKGINFO
echo "size = $size" >>.PKGINFO echo "size = $size" >>.PKGINFO
@ -631,6 +731,9 @@ if [ "$CARCH" != "" ]; then
echo "arch = $CARCH" >>.PKGINFO echo "arch = $CARCH" >>.PKGINFO
fi fi
for it in "${license[@]}"; do
echo "license = $it" >>.PKGINFO
done
for it in "${replaces[@]}"; do for it in "${replaces[@]}"; do
echo "replaces = $it" >>.PKGINFO echo "replaces = $it" >>.PKGINFO
done done
@ -677,16 +780,27 @@ if [ "$CLEANUP" = "1" ]; then
rm -rf src pkg filelist rm -rf src pkg filelist
fi fi
if [ "$RMDEPS" = "1" -a "`id -u`" = "0" -a "$INFAKEROOT" != "1" ]; then if [ "$RMDEPS" = "1" -a "`id -u`" = "0" -a "$INFAKEROOT" != "1" -a \( ! -z "$deplist" -o ! -z "$makedeplist" \) ]; then
msg "Removing installed dependencies..." msg "Removing installed dependencies..."
pacman -R $makedeplist $deplist pacman $PACMAN_OPTS -R $makedeplist $deplist
elif [ "$RMDEPS" = "1" -a "$DEP_SUDO" = "1" ]; then
msg "Removing installed dependencies..."
if [ "$INFAKEROOT" = "1" ]; then
FAKEROOTKEY2=$FAKEROOTKEY
unset FAKEROOTKEY
fi
sudo pacman $PACMAN_OPTS -R $makedeplist $deplist
if [ "$INFAKEROOT" = "1" ]; then
export FAKEROOTKEY=$FAKEROOTKEY2
unset FAKEROOTKEY2
fi
fi fi
msg "Finished making: $pkgname (`date`)" msg "Finished making: $pkgname (`date`)"
if [ "$INSTALL" = "1" -a "`id -u`" = "0" -a "$INFAKEROOT" != "1" ]; then if [ "$INSTALL" = "1" -a "`id -u`" = "0" -a "$INFAKEROOT" != "1" ]; then
msg "Running pacman --upgrade..." msg "Installing package with pacman -U..."
pacman --upgrade $PKGDEST/${pkgname}-${pkgver}-${pkgrel}.pkg.tar.gz pacman $PACMAN_OPTS -U $PKGDEST/${pkgname}-${pkgver}-${pkgrel}.pkg.tar.gz
exit $? exit $?
fi fi

View file

@ -2,7 +2,7 @@
# #
# makeworld # makeworld
# #
# Copyright (c) 2002-2004 by Judd Vinet <jvinet@zeroflux.org> # Copyright (c) 2002-2006 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,13 +20,15 @@
# USA. # USA.
# #
version="2.9.8"
toplevel=`pwd` toplevel=`pwd`
version="2.9.1"
usage() { usage() {
echo "makeworld version $version" echo "makeworld version $version"
echo "usage: $0 [options] <destdir> <category> [category] ..." echo
echo "options:" echo "Usage: $0 [options] <destdir> <category> [category] ..."
echo
echo "Options:"
echo " -b, --builddeps Build missing dependencies from source" echo " -b, --builddeps Build missing dependencies from source"
echo " -c, --clean Clean up work files after build" echo " -c, --clean Clean up work files after build"
echo " -d, --nodeps Skip all dependency checks" echo " -d, --nodeps Skip all dependency checks"
@ -36,10 +38,15 @@ usage() {
echo " -r, --rmdeps Remove installed dependencies after a successful build" echo " -r, --rmdeps Remove installed dependencies after a successful build"
echo " -s, --syncdeps Install missing dependencies with pacman" echo " -s, --syncdeps Install missing dependencies with pacman"
echo echo
echo " where <category> is one or more directory names under the ABS root" echo "These options can be passed to pacman:"
echo " eg: makeworld -c /packages base lib editors"
echo echo
echo " this should be run from the toplevel directory of ABS (usually /var/abs)" echo " --noconfirm Do not ask for confirmation when resolving dependencies"
echo " --noprogressbar Do not show a progress bar when downloading files"
echo
echo "Where <category> is one or more directory names under the ABS root"
echo "eg: makeworld -c /packages base lib editors"
echo
echo "This should be run from the toplevel directory of ABS (usually /var/abs)"
} }
if [ $# -lt 2 ]; then if [ $# -lt 2 ]; then
@ -50,6 +57,10 @@ fi
MAKEPKG_OPTS= MAKEPKG_OPTS=
for arg in $*; do for arg in $*; do
case $arg in case $arg in
# pacman
--noconfirm) MAKEPKG_OPTS="$MAKEPKG_OPTS --noconfirm" ;;
--noprogressbar) MAKEPKG_OPTS="$MAKEPKG_OPTS --noprogressbar" ;;
# makepkg
--clean) MAKEPKG_OPTS="$MAKEPKG_OPTS -c" ;; --clean) MAKEPKG_OPTS="$MAKEPKG_OPTS -c" ;;
--install) MAKEPKG_OPTS="$MAKEPKG_OPTS -i" ;; --install) MAKEPKG_OPTS="$MAKEPKG_OPTS -i" ;;
--syncdeps) MAKEPKG_OPTS="$MAKEPKG_OPTS -s" ;; --syncdeps) MAKEPKG_OPTS="$MAKEPKG_OPTS -s" ;;
@ -106,12 +117,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
View file

@ -0,0 +1,114 @@
#!/bin/bash
#
# pacman-optimize
#
# Copyright (c) 2002-2006 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.8'
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..."
find $dbroot -type f | sort | xargs 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"
find $dbroot -type f | sort | xargs 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 database"
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 # 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-2006 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.1' myver='2.9.8'
usage() { usage() {
echo "updatesync $myver" echo "updatesync $myver"
@ -54,6 +54,18 @@ die()
exit 1 exit 1
} }
check_option() {
local i
for i in ${options[@]}; do
local uc=`echo $i | tr [:lower:] [:upper:]`
local lc=`echo $i | tr [:upper:] [:lower:]`
if [ "$uc" = "$1" -o "$lc" = "$1" ]; then
echo $1
return
fi
done
}
get_md5checksum() get_md5checksum()
{ {
if [ "$pkgdir" != "" ]; then if [ "$pkgdir" != "" ]; then
@ -72,7 +84,7 @@ get_md5checksum()
db_write_entry() db_write_entry()
{ {
unset pkgname pkgver pkgrel pkgdesc force unset pkgname pkgver pkgrel pkgdesc force
unset groups replaces provides depends conflicts unset groups replaces provides depends conflicts options
source $1 || return 1 source $1 || return 1
cd $ustmpdir cd $ustmpdir
mkdir $pkgname-$pkgver-$pkgrel || return 1 mkdir $pkgname-$pkgver-$pkgrel || return 1
@ -110,7 +122,7 @@ db_write_entry()
done done
echo "" >>desc echo "" >>desc
fi fi
if [ "$force" = "y" -o "$force" = "Y" ]; then if [ "$force" = "y" -o "$force" = "Y" -o "`check_option FORCE`" ]; then
echo "%FORCE%" >>desc echo "%FORCE%" >>desc
echo "" >>desc echo "" >>desc
fi fi
@ -157,7 +169,7 @@ delete_entry()
if [ $# -lt 3 ]; then if [ $# -lt 3 ]; then
usage usage
exit 0 exit 1
fi fi
if [ "$1" = "-h" -o "$1" = "--help" ]; then if [ "$1" = "-h" -o "$1" = "--help" ]; then
@ -210,12 +222,15 @@ if [ "$action" = "upd" ]; then
else else
pkgfile="$destdir/$pkgname-$pkgver-$pkgrel.pkg.tar.gz" pkgfile="$destdir/$pkgname-$pkgver-$pkgrel.pkg.tar.gz"
fi fi
[ -f $pkgfile ] || die "missing package file: $pkgfile" if [ -f $pkgfile ]; then
csize=`du -b $pkgfile | cut -f1` csize=`du -b $pkgfile | cut -f1`
pkgmd5sum=`get_md5checksum $pkgfile` pkgmd5sum=`get_md5checksum $pkgfile`
[ -z $pkgmd5sum ] && die "error generating checksum for $pkgfile" [ -z $pkgmd5sum ] && die "error generating checksum for $pkgfile"
echo "updatesync: creating entry for $option" >&2 echo "updatesync: creating entry for $option" >&2
db_write_entry $option || die "error writing entry for $option" db_write_entry $option || die "error writing entry for $option"
else
echo "updatesync: missing package: $pkgfile" >&2
fi
else else
# DELETE # DELETE
delete_entry $option delete_entry $option

View file

@ -1,7 +1,7 @@
/* /*
* convertdb.c * convertdb.c
* *
* Copyright (c) 2002-2004 by Judd Vinet <jvinet@zeroflux.org> * Copyright (c) 2002-2006 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
@ -28,15 +28,17 @@
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <unistd.h> #include <unistd.h>
#include "pacconf.h"
#include "list.h" #include "list.h"
#include "util.h" #include "util.h"
unsigned short pmo_verbose = 0;
int main(int argc, char* argv[]) int main(int argc, char* argv[])
{ {
FILE* db = NULL; FILE* db = NULL;
FILE* fp = NULL; FILE* fp = NULL;
char* ptr = NULL; char* ptr = NULL;
char* dbdir = "/var/lib/pacman/pacman.db";
char name[256]; char name[256];
char ver[256]; char ver[256];
char line[PATH_MAX+1]; char line[PATH_MAX+1];
@ -44,6 +46,9 @@ int main(int argc, char* argv[])
char path[PATH_MAX+1]; char path[PATH_MAX+1];
mode_t oldumask; mode_t oldumask;
struct stat buf; struct stat buf;
char dbdir[PATH_MAX];
sprintf(dbdir, "/%s", PACDBDIR);
if(argc < 2) { if(argc < 2) {
printf("converts a pacman 1.x database to a pacman 2.0 format\n"); printf("converts a pacman 1.x database to a pacman 2.0 format\n");

318
src/db.c
View file

@ -1,7 +1,7 @@
/* /*
* db.c * db.c
* *
* Copyright (c) 2002-2004 by Judd Vinet <jvinet@zeroflux.org> * Copyright (c) 2002-2006 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
@ -29,6 +29,7 @@
#include <libgen.h> #include <libgen.h>
#include <unistd.h> #include <unistd.h>
#include "package.h" #include "package.h"
#include "strhash.h"
#include "util.h" #include "util.h"
#include "db.h" #include "db.h"
@ -131,25 +132,74 @@ pkginfo_t* db_scan(pacdb_t *db, char *target, unsigned int inforeq)
struct dirent *ent = NULL; struct dirent *ent = NULL;
struct stat sbuf; struct stat sbuf;
char path[PATH_MAX]; char path[PATH_MAX];
char name[256]; int path_len = 0;
char *name = NULL;
char *ptr = NULL; char *ptr = NULL;
int found = 0; int found = 0;
/* 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) { 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. */
strcat(path, target);
if(strhash_isin(db_htable, path)) {
struct dirent* pkgdir;
pkginfo_t* pkg;
/* db_read() wants 'struct dirent' so lets give it one.
* Actually it only uses the d_name field. */
MALLOC(pkgdir, sizeof(struct dirent));
strcpy(pkgdir->d_name, strhash_get(db_htable, path));
pkg = db_read(db, pkgdir, inforeq);
FREE(pkgdir);
return pkg;
}
path[path_len] = '\0';
/* OK the entry was not in cache, so lets look for it manually. */
rewinddir(db->dir); rewinddir(db->dir);
ent = readdir(db->dir); ent = readdir(db->dir);
while(!found && ent != NULL) { while(!found && ent != NULL) {
if(!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, "..")) { if(!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, "..")) {
ent = readdir(db->dir); ent = readdir(db->dir);
continue; continue;
} }
strncpy(name, ent->d_name, 255);
/* stat the entry, make sure it's a directory */ /* stat the entry, make sure it's a directory */
snprintf(path, PATH_MAX, "%s/%s", db->path, name); path[path_len] = '\0';
strncat(path, ent->d_name, PATH_MAX - path_len);
if(stat(path, &sbuf) || !S_ISDIR(sbuf.st_mode)) { if(stat(path, &sbuf) || !S_ISDIR(sbuf.st_mode)) {
ent = readdir(db->dir);
continue; continue;
} }
name = path + path_len;
/* truncate the string at the second-to-last hyphen, */ /* truncate the string at the second-to-last hyphen, */
/* which will give us the package name */ /* which will give us the package name */
if((ptr = rindex(name, '-'))) { if((ptr = rindex(name, '-'))) {
@ -175,8 +225,11 @@ pkginfo_t* db_scan(pacdb_t *db, char *target, unsigned int inforeq)
if(ent == NULL) { if(ent == NULL) {
return(NULL); return(NULL);
} }
/* stat the entry, make sure it's a directory */ /* stat the entry, make sure it's a directory */
snprintf(path, PATH_MAX, "%s/%s", db->path, ent->d_name); path[path_len] = '\0';
strncat(path, ent->d_name, PATH_MAX - path_len);
if(!stat(path, &sbuf) && S_ISDIR(sbuf.st_mode)) { if(!stat(path, &sbuf) && S_ISDIR(sbuf.st_mode)) {
isdir = 1; isdir = 1;
} }
@ -184,6 +237,25 @@ pkginfo_t* db_scan(pacdb_t *db, char *target, unsigned int inforeq)
isdir = 0; isdir = 0;
continue; continue;
} }
name = path + path_len;
if((ptr = rindex(name, '-'))) {
*ptr = '\0';
}
if((ptr = rindex(name, '-'))) {
*ptr = '\0';
}
/* Add entries like:
*
* key: /var/lib/pacman/extra/xrally
* data: xrally-1.1.1-1
*/
if(!strhash_isin(db_htable, path)) {
strhash_add(db_htable, strdup(path), strdup(ent->d_name));
}
} }
} }
return(db_read(db, ent, inforeq)); return(db_read(db, ent, inforeq));
@ -255,12 +327,6 @@ pkginfo_t* db_read(pacdb_t *db, struct dirent *ent, unsigned int inforeq)
return(NULL); return(NULL);
} }
trim(info->url); trim(info->url);
} else if(!strcmp(line, "%LICENSE%")) {
if(fgets(info->license, sizeof(info->license), fp) == NULL) {
FREEPKG(info);
return(NULL);
}
trim(info->license);
} else if(!strcmp(line, "%ARCH%")) { } else if(!strcmp(line, "%ARCH%")) {
if(fgets(info->arch, sizeof(info->arch), fp) == NULL) { if(fgets(info->arch, sizeof(info->arch), fp) == NULL) {
FREEPKG(info); FREEPKG(info);
@ -314,6 +380,11 @@ pkginfo_t* db_read(pacdb_t *db, struct dirent *ent, unsigned int inforeq)
} }
trim(tmp); trim(tmp);
info->size = atol(tmp); info->size = atol(tmp);
} else if(!strcmp(line, "%LICENSE%")) {
while(fgets(line, 512, fp) && strlen(trim(line))) {
char *s = strdup(line);
info->license = list_add(info->license, s);
}
} else if(!strcmp(line, "%REPLACES%")) { } else if(!strcmp(line, "%REPLACES%")) {
/* the REPLACES tag is special -- it only appears in sync repositories, /* the REPLACES tag is special -- it only appears in sync repositories,
* not the local one. */ * not the local one. */
@ -457,7 +528,10 @@ int db_write(pacdb_t *db, pkginfo_t *info, unsigned int inforeq)
fputs("%URL%\n", fp); fputs("%URL%\n", fp);
fprintf(fp, "%s\n\n", info->url); fprintf(fp, "%s\n\n", info->url);
fputs("%LICENSE%\n", fp); fputs("%LICENSE%\n", fp);
fprintf(fp, "%s\n\n", info->license); for(lp = info->license; lp; lp = lp->next) {
fprintf(fp, "%s\n", (char*)lp->data);
}
fprintf(fp, "\n");
fputs("%ARCH%\n", fp); fputs("%ARCH%\n", fp);
fprintf(fp, "%s\n\n", info->arch); fprintf(fp, "%s\n\n", info->arch);
fputs("%BUILDDATE%\n", fp); fputs("%BUILDDATE%\n", fp);
@ -534,6 +608,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;
@ -543,15 +651,13 @@ void db_search(pacdb_t *db, PMList *cache, const char *treename, PMList *needles
for(i = needles; i; i = i->next) { for(i = needles; i; i = i->next) {
char *targ = strdup(i->data); char *targ = strdup(i->data);
strtoupper(targ);
for(j = cache; j; j = j->next) { for(j = cache; j; j = j->next) {
pkginfo_t *pkg = (pkginfo_t*)j->data; pkginfo_t *pkg = (pkginfo_t*)j->data;
char *haystack; char *haystack;
int match = 0; int match = 0;
/* check name */ /* check name */
haystack = strdup(pkg->name); haystack = strdup(pkg->name);
strtoupper(haystack); if(reg_match(haystack, targ)) {
if(strstr(haystack, targ)) {
match = 1; match = 1;
} }
FREE(haystack); FREE(haystack);
@ -559,8 +665,7 @@ void db_search(pacdb_t *db, PMList *cache, const char *treename, PMList *needles
/* check description */ /* check description */
if(!match) { if(!match) {
haystack = strdup(pkg->desc); haystack = strdup(pkg->desc);
strtoupper(haystack); if(reg_match(haystack, targ)) {
if(strstr(haystack, targ)) {
match = 1; match = 1;
} }
FREE(haystack); FREE(haystack);
@ -573,8 +678,7 @@ void db_search(pacdb_t *db, PMList *cache, const char *treename, PMList *needles
if(info != NULL) { if(info != NULL) {
for(m = info->provides; m; m = m->next) { for(m = info->provides; m; m = m->next) {
haystack = strdup(m->data); haystack = strdup(m->data);
strtoupper(haystack); if(reg_match(haystack, targ)) {
if(strstr(haystack, targ)) {
match = 1; match = 1;
} }
FREE(haystack); FREE(haystack);
@ -594,7 +698,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;
@ -603,43 +707,32 @@ PMList* db_find_conflicts(pacdb_t *db, PMList *targets, char *root)
struct stat buf, buf2; struct stat buf, buf2;
PMList *conflicts = NULL; PMList *conflicts = NULL;
/* CHECK 1: check every db package against every target package */ strhash_t** htables;
/* XXX: I've disabled the database-against-targets check for now, as the int target_num = 0;
* many many strcmp() calls slow it down heavily and most of the int d = 0;
* checking is redundant to the targets-against-filesystem check. int e = 0;
* 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) {
if(i->data == NULL) continue;
dbstr = (char*)i->data;
for(j = targets; j; j = j->next) {
pkginfo_t *targ = (pkginfo_t*)j->data;
if(strcmp(info->name, targ->name)) {
for(k = targ->files; k; k = k->next) {
filestr = (char*)k->data;
if(!strcmp(dbstr, filestr)) {
if(rindex(k->data, '/') == filestr+strlen(filestr)-1) {
continue;
}
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 */ /* Create and initialise an array of hash tables.
for(i = targets; i; i = i->next) { *
* htables [ 0 ... target_num ] : targets' files
* htables [ target_num ] : used later
*/
target_num = list_count(targets);
MALLOC(htables, (target_num+1) * sizeof(strhash_t*));
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 target against every target */
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(j = i; j; j = j->next) { for(e = d, j = i; j; j = j->next, e++) {
pkginfo_t *p2 = (pkginfo_t*)j->data; pkginfo_t *p2 = (pkginfo_t*)j->data;
if(strcmp(p1->name, p2->name)) { if(strcmp(p1->name, p2->name)) {
for(k = p1->files; k; k = k->next) { for(k = p1->files; k; k = k->next) {
@ -651,7 +744,7 @@ PMList* db_find_conflicts(pacdb_t *db, PMList *targets, char *root)
/* this filename has a trailing '/', so it's a directory -- skip it. */ /* this filename has a trailing '/', so it's a directory -- skip it. */
continue; continue;
} }
if(is_in(filestr, p2->files)) { if(strhash_isin(htables[e], filestr)) {
MALLOC(str, 512); MALLOC(str, 512);
snprintf(str, 512, "%s: exists in \"%s\" (target) and \"%s\" (target)", snprintf(str, 512, "%s: exists in \"%s\" (target) and \"%s\" (target)",
filestr, p1->name, p2->name); filestr, p1->name, p2->name);
@ -662,53 +755,97 @@ 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;
for(j = p->files; j; j = j->next) { for(j = p->files; j; j = j->next) {
int isdir = 0;
filestr = (char*)j->data; filestr = (char*)j->data;
snprintf(path, PATH_MAX, "%s%s", root, filestr); snprintf(path, PATH_MAX, "%s%s", root, filestr);
if(!stat(path, &buf) && !S_ISDIR(buf.st_mode)) { /* is this target a file or directory? */
if(path[strlen(path)-1] == '/') {
isdir = 1;
path[strlen(path)-1] = '\0';
}
if(!lstat(path, &buf)) {
int ok = 0; int ok = 0;
if(dbpkg == NULL) { if(!S_ISLNK(buf.st_mode) && ((isdir && !S_ISDIR(buf.st_mode)) || (!isdir && S_ISDIR(buf.st_mode)))) {
dbpkg = db_scan(db, p->name, INFRQ_DESC | INFRQ_FILES); /* if the package target is a directory, and the filesystem target
* is not (or vice versa) then it's a conflict
*/
ok = 0;
goto donecheck;
} }
if(dbpkg && is_in(j->data, dbpkg->files)) { /* re-fetch with stat() instead of lstat() */
stat(path, &buf);
if(S_ISDIR(buf.st_mode)) {
/* if it's a directory, then we have no conflict */
ok = 1; ok = 1;
} } else {
/* Make sure that the supposedly-conflicting file is not actually just if(dbpkg == NULL) {
* a symlink that points to a path that used to exist in the package. dbpkg = db_scan(db, p->name, INFRQ_DESC | INFRQ_FILES);
*/
/* Check if any part of the conflicting file's path is a symlink */ if(dbpkg)
if(dbpkg && !ok) { strhash_add_list(htables[target_num], dbpkg->files);
MALLOC(str, PATH_MAX);
for(k = dbpkg->files; k; k = k->next) {
snprintf(str, PATH_MAX, "%s%s", root, (char*)k->data);
stat(str, &buf2);
if(buf.st_ino == buf2.st_ino) {
ok = 1;
}
} }
FREE(str); if(dbpkg && strhash_isin(htables[target_num], filestr)) {
} ok = 1;
/* Check if the conflicting file has been moved to another package/target */ }
if(!ok) { /* Make sure that the supposedly-conflicting file is not actually just
/* Look at all the targets */ * a symlink that points to a path that used to exist in the package.
for(k = targets; k && !ok; k = k->next) { */
pkginfo_t *p1 = (pkginfo_t*)k->data; /* Check if any part of the conflicting file's path is a symlink */
/* As long as they're not the current package */ if(dbpkg && !ok) {
if(strcmp(p1->name, p->name)) { MALLOC(str, PATH_MAX);
pkginfo_t *dbpkg2 = NULL; for(k = dbpkg->files; k; k = k->next) {
dbpkg2 = db_scan(db, p1->name, INFRQ_DESC | INFRQ_FILES); snprintf(str, PATH_MAX, "%s%s", root, (char*)k->data);
/* If it used to exist in there, but doesn't anymore */ stat(str, &buf2);
if(dbpkg2 && !is_in(filestr, p1->files) && is_in(filestr, dbpkg2->files)) { 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;
} }
FREEPKG(dbpkg2); }
FREE(str);
}
/* Check if the conflicting file has been moved to another package/target */
if(!ok) {
/* Look at all the targets */
for(k = targets; k && !ok; k = k->next) {
pkginfo_t *p1 = (pkginfo_t*)k->data;
/* As long as they're not the current package */
if(strcmp(p1->name, p->name)) {
pkginfo_t *dbpkg2 = NULL;
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);
}
} }
} }
} }
donecheck:
if(!ok) { if(!ok) {
MALLOC(str, 512); MALLOC(str, 512);
snprintf(str, 512, "%s: %s: exists in filesystem", p->name, path); snprintf(str, 512, "%s: %s: exists in filesystem", p->name, path);
@ -719,6 +856,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);
} }

View file

@ -1,7 +1,7 @@
/* /*
* db.h * db.h
* *
* Copyright (c) 2002-2004 by Judd Vinet <jvinet@zeroflux.org> * Copyright (c) 2002-2006 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
@ -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);

View file

@ -1,7 +1,7 @@
/* /*
* list.c * list.c
* *
* Copyright (c) 2002-2004 by Judd Vinet <jvinet@zeroflux.org> * Copyright (c) 2002-2006 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
@ -23,8 +23,33 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <stdio.h> #include <stdio.h>
#include <assert.h>
#include "list.h" #include "list.h"
/* Check PMList sanity
*
* 1: List seems to be OK.
* 0: We're in deep ...
*/
int check_list(PMList* list)
{
PMList* it = NULL;
if(list == NULL) {
return(1);
}
if(list->last == NULL) {
return(0);
}
for(it = list; it && it->next; it = it->next);
if(it != list->last) {
return(0);
}
return(1);
}
PMList* list_new() PMList* list_new()
{ {
PMList *list = NULL; PMList *list = NULL;
@ -36,22 +61,20 @@ PMList* list_new()
list->data = NULL; list->data = NULL;
list->prev = NULL; list->prev = NULL;
list->next = NULL; list->next = NULL;
list->last = list;
return(list); return(list);
} }
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;
} }
@ -62,6 +85,8 @@ PMList* list_add(PMList *list, void *data)
ptr = list; ptr = list;
if(ptr == NULL) { if(ptr == NULL) {
ptr = list_new(); ptr = list_new();
if (!ptr)
return(NULL);
} }
lp = list_last(ptr); lp = list_last(ptr);
@ -73,12 +98,67 @@ PMList* list_add(PMList *list, void *data)
return(NULL); return(NULL);
} }
lp->next->prev = lp; lp->next->prev = lp;
lp->last = NULL;
lp = lp->next; lp = lp->next;
} }
lp->data = data; lp->data = data;
ptr->last = lp;
return(ptr); return(ptr);
} }
/* list: the beginning of the list
* item: the item in the list to be removed
*
* returns:
* list with item removed
*/
PMList* list_remove(PMList* list, PMList* item)
{
assert(check_list(list));
if (list == NULL || item == NULL)
return NULL;
/* Remove first item in list. */
if (item == list) {
if (list->next == NULL) { /* Only item in list. */
list_free(item);
return NULL;
} else {
list->next->prev = NULL;
list->next->last = list->last;
list = list->next;
item->prev = item->next = NULL;
list_free(item);
return list;
}
}
/* Remove last item in list. */
if (list->last == item) {
list->last = item->prev;
item->prev->next = NULL;
item->prev = item->next = NULL;
list_free(item);
return list;
}
/* Remove middle item in list. */
assert(item->prev != NULL &&
item->next != NULL);
item->prev->next = item->next;
item->next->prev = item->prev;
item->prev = item->next = NULL;
list_free(item);
assert(check_list(list));
return list;
}
int list_count(PMList *list) int list_count(PMList *list)
{ {
int i; int i;
@ -141,10 +221,11 @@ PMList* list_merge(PMList *one, PMList *two)
PMList* list_last(PMList *list) PMList* list_last(PMList *list)
{ {
PMList *ptr; if (list == NULL)
return NULL;
for(ptr = list; ptr && ptr->next; ptr = ptr->next); assert(list->last != NULL);
return(ptr); return list->last;
} }
/* Helper function for sorting a list of strings /* Helper function for sorting a list of strings
@ -157,6 +238,8 @@ int list_strcmp(const void *s1, const void *s2)
return(strcmp(*str1, *str2)); return(strcmp(*str1, *str2));
} }
/* Sort a list of strings.
*/
PMList *list_sort(PMList *list) PMList *list_sort(PMList *list)
{ {
char **arr = NULL; char **arr = NULL;
@ -189,6 +272,42 @@ PMList *list_sort(PMList *list)
return(lp); return(lp);
} }
/* Filter out any duplicate strings in a list.
*
* Not the most efficient way, but simple to implement -- we assemble
* a new list, using is_in() to check for dupes at each iteration.
*
*/
PMList* list_remove_dupes(PMList *list)
{
PMList *i, *newlist = NULL;
for(i = list; i; i = i->next) {
if(!is_in(i->data, newlist)) {
newlist = list_add(newlist, strdup(i->data));
}
}
return newlist;
}
/* Reverse the order of a list
*
* The caller is responsible for freeing the old list
*/
PMList* list_reverse(PMList *list)
{
/* simple but functional -- we just build a new list, starting
* with the old list's tail
*/
PMList *newlist = NULL;
PMList *lp;
for(lp = list->last; lp; lp = lp->prev) {
newlist = list_add(newlist, lp->data);
}
return(newlist);
}
void list_display(const char *title, PMList *list) void list_display(const char *title, PMList *list)
{ {
PMList *lp; PMList *lp;
@ -257,11 +376,24 @@ PMList* list_add_sorted(PMList *list, void *data, cmp_fn sortfunc)
/* Insert node before insertion point. */ /* Insert node before insertion point. */
add->prev = prev; add->prev = prev;
add->next = iter; add->next = iter;
if(iter != NULL) iter->prev = add; /* Not at end. */
if(prev != NULL) { if(iter != NULL) {
prev->next = add; /* In middle. */ iter->prev = add; /* Not at end. */
} else { } else {
list = add; /* Start or empty, new list head. */ if (list != NULL)
list->last = add; /* Added new to end, so update the link to last. */
}
if(prev != NULL) {
prev->next = add; /* In middle. */
} else {
if (list == NULL) {
add->last = add;
} else {
add->last = list->last;
list->last = NULL;
}
list = add; /* Start or empty, new list head. */
} }
return(list); return(list);

View file

@ -1,7 +1,7 @@
/* /*
* list.h * list.h
* *
* Copyright (c) 2002-2004 by Judd Vinet <jvinet@zeroflux.org> * Copyright (c) 2002-2006 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
@ -28,6 +28,7 @@ typedef struct __pmlist_t {
void* data; void* data;
struct __pmlist_t* prev; struct __pmlist_t* prev;
struct __pmlist_t* next; struct __pmlist_t* next;
struct __pmlist_t* last; /* Quick access to last item in list */
} PMList; } PMList;
@ -38,6 +39,7 @@ typedef int (*cmp_fn) (const void *, const void *);
PMList* list_new(); PMList* list_new();
void list_free(PMList* list); void list_free(PMList* list);
PMList* list_add(PMList* list, void* data); PMList* list_add(PMList* list, void* data);
PMList* list_remove(PMList* list, PMList* item);
int list_count(PMList* list); int list_count(PMList* list);
int list_isin(PMList *haystack, void *needle); int list_isin(PMList *haystack, void *needle);
PMList* is_in(char *needle, PMList *haystack); PMList* is_in(char *needle, PMList *haystack);
@ -45,6 +47,8 @@ PMList* list_merge(PMList *one, PMList *two);
PMList* list_last(PMList* list); PMList* list_last(PMList* list);
int list_strcmp(const void *s1, const void *s2); int list_strcmp(const void *s1, const void *s2);
PMList *list_sort(PMList *list); PMList *list_sort(PMList *list);
PMList* list_remove_dupes(PMList *list);
PMList *list_reverse(PMList *list);
void list_display(const char *title, PMList *list); void list_display(const char *title, PMList *list);
int strlist_cmp(const void *s1, const void *s2); int strlist_cmp(const void *s1, const void *s2);

View file

@ -23,6 +23,7 @@ These notices must be retained in any copies of any part of this
documentation and/or software. documentation and/or software.
*/ */
#include <string.h>
#include "md5.h" #include "md5.h"
/* Constants for MD5Transform routine. /* Constants for MD5Transform routine.
@ -48,8 +49,8 @@ documentation and/or software.
static void MD5Transform(UINT4 [4], unsigned char [64]); static void MD5Transform(UINT4 [4], unsigned char [64]);
static void Encode(unsigned char *, UINT4 *, unsigned int); static void Encode(unsigned char *, UINT4 *, unsigned int);
static void Decode(UINT4 *, unsigned char *, unsigned int); static void Decode(UINT4 *, unsigned char *, unsigned int);
static void MD5_memcpy(POINTER, POINTER, unsigned int); /* static void MD5_memcpy(POINTER, POINTER, unsigned int); */
static void MD5_memset(POINTER, int, unsigned int); /* static void MD5_memset(POINTER, int, unsigned int); */
static unsigned char PADDING[64] = { static unsigned char PADDING[64] = {
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@ -132,8 +133,7 @@ unsigned int inputLen; /* length of input block */
/* Transform as many times as possible. /* Transform as many times as possible.
*/ */
if (inputLen >= partLen) { if (inputLen >= partLen) {
MD5_memcpy memcpy ((POINTER)&context->buffer[index], (POINTER)input, partLen);
((POINTER)&context->buffer[index], (POINTER)input, partLen);
MD5Transform (context->state, context->buffer); MD5Transform (context->state, context->buffer);
for (i = partLen; i + 63 < inputLen; i += 64) for (i = partLen; i + 63 < inputLen; i += 64)
@ -145,9 +145,7 @@ unsigned int inputLen; /* length of input block */
i = 0; i = 0;
/* Buffer remaining input */ /* Buffer remaining input */
MD5_memcpy memcpy ((POINTER)&context->buffer[index], (POINTER)&input[i], inputLen-i);
((POINTER)&context->buffer[index], (POINTER)&input[i],
inputLen-i);
} }
/* MD5 finalization. Ends an MD5 message-digest operation, writing the /* MD5 finalization. Ends an MD5 message-digest operation, writing the
@ -177,7 +175,7 @@ MD5_CTX *context; /* context */
/* Zeroize sensitive information. /* Zeroize sensitive information.
*/ */
MD5_memset ((POINTER)context, 0, sizeof (*context)); memset ((POINTER)context, 0, sizeof (*context));
} }
/* MD5 basic transformation. Transforms state based on block. /* MD5 basic transformation. Transforms state based on block.
@ -271,7 +269,7 @@ unsigned char block[64];
/* Zeroize sensitive information. /* Zeroize sensitive information.
*/ */
MD5_memset ((POINTER)x, 0, sizeof (x)); memset ((POINTER)x, 0, sizeof (x));
} }
/* Encodes input (UINT4) into output (unsigned char). Assumes len is /* Encodes input (UINT4) into output (unsigned char). Assumes len is
@ -310,7 +308,7 @@ unsigned int len;
/* Note: Replace "for loop" with standard memcpy if possible. /* Note: Replace "for loop" with standard memcpy if possible.
*/ */
static void MD5_memcpy (output, input, len) /* static void MD5_memcpy (output, input, len)
POINTER output; POINTER output;
POINTER input; POINTER input;
unsigned int len; unsigned int len;
@ -321,10 +319,10 @@ unsigned int len;
output[i] = input[i]; output[i] = input[i];
} }
*/
/* Note: Replace "for loop" with standard memset if possible. /* Note: Replace "for loop" with standard memset if possible.
*/ */
static void MD5_memset (output, value, len) /* static void MD5_memset (output, value, len)
POINTER output; POINTER output;
int value; int value;
unsigned int len; unsigned int len;
@ -334,5 +332,5 @@ unsigned int len;
for (i = 0; i < len; i++) for (i = 0; i < len; i++)
((char *)output)[i] = (char)value; ((char *)output)[i] = (char)value;
} }
*/
/* vim: set ts=2 sw=2 noet: */ /* vim: set ts=2 sw=2 noet: */

View file

@ -31,7 +31,7 @@ typedef unsigned char *POINTER;
typedef unsigned short int UINT2; typedef unsigned short int UINT2;
/* UINT4 defines a four byte word */ /* UINT4 defines a four byte word */
typedef unsigned long int UINT4; typedef unsigned int UINT4;
/* MD5 context. */ /* MD5 context. */

46
src/pacconf.h Normal file
View file

@ -0,0 +1,46 @@
/*
* pacconf.h
*
* Copyright (c) 2002-2006 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.
*/
#ifndef _PAC_PACCONF_H
#define _PAC_PACCONF_H
#ifndef PACVER
#define PACVER "2.9.8"
#endif
#ifndef PACDBDIR
#define PACDBDIR "var/lib/pacman"
#endif
#ifndef PKGEXT
#define PKGEXT ".pkg.tar.gz"
#endif
#ifndef PACCONF
#define PACCONF "/etc/pacman.conf"
#endif
#ifndef CACHEDIR
#define CACHEDIR "var/cache/pacman/pkg"
#endif
#endif /* PACCONF_H */
/* vim: set ts=2 sw=2 noet: */

View file

@ -1,7 +1,7 @@
/* /*
* package.c * package.c
* *
* Copyright (c) 2002-2004 by Judd Vinet <jvinet@zeroflux.org> * Copyright (c) 2002-2006 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
@ -27,6 +27,7 @@
#include <string.h> #include <string.h>
#include <libtar.h> #include <libtar.h>
#include <zlib.h> #include <zlib.h>
#include "pacconf.h"
#include "util.h" #include "util.h"
#include "package.h" #include "package.h"
@ -62,21 +63,28 @@ pkginfo_t* load_pkg(char *pkgfile)
} }
if(!strcmp(th_get_pathname(tar), ".PKGINFO")) { if(!strcmp(th_get_pathname(tar), ".PKGINFO")) {
char *descfile; char *descfile;
int fd;
/* extract this file into /tmp. it has info for us */ /* extract this file into /tmp. it has info for us */
descfile = strdup("/tmp/pacman_XXXXXX"); descfile = strdup("/tmp/pacman_XXXXXX");
mkstemp(descfile); fd = mkstemp(descfile);
tar_extract_file(tar, descfile); tar_extract_file(tar, descfile);
/* parse the info file */ /* parse the info file */
parse_descfile(descfile, info, &backup, 0); parse_descfile(descfile, info, &backup, 0);
if(!strlen(info->name)) { if(!strlen(info->name)) {
fprintf(stderr, "load_pkg: missing package name in %s.\n", pkgfile); fprintf(stderr, "load_pkg: missing package name in %s.\n", pkgfile);
FREEPKG(info); FREEPKG(info);
unlink(descfile);
FREE(descfile);
close(fd);
return(NULL); return(NULL);
} }
if(!strlen(info->version)) { if(!strlen(info->version)) {
fprintf(stderr, "load_pkg: missing package version in %s.\n", pkgfile); fprintf(stderr, "load_pkg: missing package version in %s.\n", pkgfile);
FREEPKG(info); FREEPKG(info);
unlink(descfile);
FREE(descfile);
close(fd);
return(NULL); return(NULL);
} }
for(lp = backup; lp; lp = lp->next) { for(lp = backup; lp; lp = lp->next) {
@ -85,7 +93,9 @@ pkginfo_t* load_pkg(char *pkgfile)
} }
} }
config = 1; config = 1;
unlink(descfile);
FREE(descfile); FREE(descfile);
close(fd);
continue; continue;
} else if(!strcmp(th_get_pathname(tar), "._install") || !strcmp(th_get_pathname(tar), ".INSTALL")) { } else if(!strcmp(th_get_pathname(tar), "._install") || !strcmp(th_get_pathname(tar), ".INSTALL")) {
info->scriptlet = 1; info->scriptlet = 1;
@ -95,10 +105,11 @@ pkginfo_t* load_pkg(char *pkgfile)
FILE *fp; FILE *fp;
char *fn; char *fn;
char *str; char *str;
int fd;
MALLOC(str, PATH_MAX); MALLOC(str, PATH_MAX);
fn = strdup("/tmp/pacman_XXXXXX"); fn = strdup("/tmp/pacman_XXXXXX");
mkstemp(fn); fd = mkstemp(fn);
tar_extract_file(tar, fn); tar_extract_file(tar, fn);
fp = fopen(fn, "r"); fp = fopen(fn, "r");
while(!feof(fp)) { while(!feof(fp)) {
@ -114,6 +125,7 @@ pkginfo_t* load_pkg(char *pkgfile)
fprintf(stderr, "warning: could not remove tempfile %s\n", fn); fprintf(stderr, "warning: could not remove tempfile %s\n", fn);
} }
FREE(fn); FREE(fn);
close(fd);
filelist = 1; filelist = 1;
continue; continue;
} else { } else {
@ -143,6 +155,8 @@ pkginfo_t* load_pkg(char *pkgfile)
return(NULL); return(NULL);
} }
info->filename = strdup(pkgfile);
return(info); return(info);
} }
@ -194,8 +208,6 @@ int parse_descfile(char *descfile, pkginfo_t *info, PMList **backup, int output)
info->groups = list_add(info->groups, strdup(ptr)); info->groups = list_add(info->groups, strdup(ptr));
} else if(!strcmp(key, "URL")) { } else if(!strcmp(key, "URL")) {
strncpy(info->url, ptr, sizeof(info->url)); strncpy(info->url, ptr, sizeof(info->url));
} else if(!strcmp(key, "LICENSE")) {
strncpy(info->license, ptr, sizeof(info->license));
} else if(!strcmp(key, "BUILDDATE")) { } else if(!strcmp(key, "BUILDDATE")) {
strncpy(info->builddate, ptr, sizeof(info->builddate)); strncpy(info->builddate, ptr, sizeof(info->builddate));
} else if(!strcmp(key, "INSTALLDATE")) { } else if(!strcmp(key, "INSTALLDATE")) {
@ -208,6 +220,8 @@ int parse_descfile(char *descfile, pkginfo_t *info, PMList **backup, int output)
char tmp[32]; char tmp[32];
strncpy(tmp, ptr, sizeof(tmp)); strncpy(tmp, ptr, sizeof(tmp));
info->size = atol(tmp); info->size = atol(tmp);
} else if(!strcmp(key, "LICENSE")) {
info->license = list_add(info->license, strdup(ptr));
} else if(!strcmp(key, "DEPEND")) { } else if(!strcmp(key, "DEPEND")) {
info->depends = list_add(info->depends, strdup(ptr)); info->depends = list_add(info->depends, strdup(ptr));
} else if(!strcmp(key, "CONFLICT")) { } else if(!strcmp(key, "CONFLICT")) {
@ -241,7 +255,6 @@ pkginfo_t* newpkg()
pkg->version[0] = '\0'; pkg->version[0] = '\0';
pkg->desc[0] = '\0'; pkg->desc[0] = '\0';
pkg->url[0] = '\0'; pkg->url[0] = '\0';
pkg->license[0] = '\0';
pkg->builddate[0] = '\0'; pkg->builddate[0] = '\0';
pkg->installdate[0] = '\0'; pkg->installdate[0] = '\0';
pkg->packager[0] = '\0'; pkg->packager[0] = '\0';
@ -251,6 +264,7 @@ pkginfo_t* newpkg()
pkg->scriptlet = 0; pkg->scriptlet = 0;
pkg->force = 0; pkg->force = 0;
pkg->reason = REASON_EXPLICIT; pkg->reason = REASON_EXPLICIT;
pkg->license = NULL;
pkg->requiredby = NULL; pkg->requiredby = NULL;
pkg->conflicts = NULL; pkg->conflicts = NULL;
pkg->files = NULL; pkg->files = NULL;
@ -259,6 +273,7 @@ pkginfo_t* newpkg()
pkg->groups = NULL; pkg->groups = NULL;
pkg->provides = NULL; pkg->provides = NULL;
pkg->replaces = NULL; pkg->replaces = NULL;
pkg->filename = NULL;
return(pkg); return(pkg);
} }
@ -277,6 +292,7 @@ void freepkg(pkginfo_t *pkg)
FREELIST(pkg->groups); FREELIST(pkg->groups);
FREELIST(pkg->provides); FREELIST(pkg->provides);
FREELIST(pkg->replaces); FREELIST(pkg->replaces);
FREE(pkg->filename);
FREE(pkg); FREE(pkg);
return; return;
} }
@ -335,7 +351,9 @@ void dump_pkg_full(pkginfo_t *info)
FREELIST(pm); FREELIST(pm);
printf("Packager : %s\n", info->packager); printf("Packager : %s\n", info->packager);
printf("URL : %s\n", info->url); printf("URL : %s\n", info->url);
printf("License : %s\n", info->license); pm = list_sort(info->license);
list_display("License :", pm);
FREELIST(pm);
printf("Architecture : %s\n", info->arch); printf("Architecture : %s\n", info->arch);
printf("Size : %ld\n", info->size); printf("Size : %ld\n", info->size);
printf("Build Date : %s %s\n", info->builddate, strlen(info->builddate) ? "UTC" : ""); printf("Build Date : %s %s\n", info->builddate, strlen(info->builddate) ? "UTC" : "");
@ -366,7 +384,7 @@ void dump_pkg_full(pkginfo_t *info)
/* Display the content of a sync package /* Display the content of a sync package
*/ */
void dump_pkg_sync(pkginfo_t *info) void dump_pkg_sync(pkginfo_t *info, char *treename)
{ {
PMList *pm; PMList *pm;
@ -374,6 +392,7 @@ void dump_pkg_sync(pkginfo_t *info)
return; return;
} }
printf("Repository : %s\n", treename);
printf("Name : %s\n", info->name); printf("Name : %s\n", info->name);
printf("Version : %s\n", info->version); printf("Version : %s\n", info->version);
pm = list_sort(info->groups); pm = list_sort(info->groups);
@ -410,7 +429,7 @@ int split_pkgname(char *pkgfile, char *name, char *version)
} }
strncpy(tmp, p, 512); strncpy(tmp, p, 512);
/* trim file extension (if any) */ /* trim file extension (if any) */
if((p = strstr(tmp, ".pkg.tar.gz"))) { if((p = strstr(tmp, PKGEXT))) {
*p = 0; *p = 0;
} }

View file

@ -1,7 +1,7 @@
/* /*
* package.h * package.h
* *
* Copyright (c) 2002-2004 by Judd Vinet <jvinet@zeroflux.org> * Copyright (c) 2002-2006 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
@ -50,7 +50,6 @@ typedef struct __pkginfo_t {
char version[64]; char version[64];
char desc[512]; char desc[512];
char url[256]; char url[256];
char license[128];
char builddate[32]; char builddate[32];
char installdate[32]; char installdate[32];
char packager[64]; char packager[64];
@ -60,6 +59,7 @@ typedef struct __pkginfo_t {
unsigned short scriptlet; unsigned short scriptlet;
unsigned short force; unsigned short force;
unsigned short reason; unsigned short reason;
PMList *license;
PMList *replaces; PMList *replaces;
PMList *groups; PMList *groups;
PMList *files; PMList *files;
@ -68,6 +68,10 @@ typedef struct __pkginfo_t {
PMList *requiredby; PMList *requiredby;
PMList *conflicts; PMList *conflicts;
PMList *provides; PMList *provides;
/* if the package has an associated filename on the local system
* (eg, filename.pkg.tar.gz) then it will be stored here, otherwise NULL
*/
char *filename;
} pkginfo_t; } pkginfo_t;
typedef struct __depend_t { typedef struct __depend_t {
@ -89,7 +93,7 @@ void freepkg(pkginfo_t *pkg);
int pkgcmp(const void *p1, const void *p2); int pkgcmp(const void *p1, const void *p2);
int is_pkgin(pkginfo_t *needle, PMList *haystack); int is_pkgin(pkginfo_t *needle, PMList *haystack);
void dump_pkg_full(pkginfo_t *info); void dump_pkg_full(pkginfo_t *info);
void dump_pkg_sync(pkginfo_t *info); void dump_pkg_sync(pkginfo_t *info, char *treename);
int split_pkgname(char *pkgfile, char *name, char *version); int split_pkgname(char *pkgfile, char *name, char *version);
#endif #endif

File diff suppressed because it is too large Load diff

View file

@ -1,7 +1,7 @@
/* /*
* pacman.h * pacman.h
* *
* Copyright (c) 2002-2004 by Judd Vinet <jvinet@zeroflux.org> * Copyright (c) 2002-2006 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
@ -21,22 +21,6 @@
#ifndef _PAC_PACMAN_H #ifndef _PAC_PACMAN_H
#define _PAC_PACMAN_H #define _PAC_PACMAN_H
#ifndef PACVER
#define PACVER "2.9.1"
#endif
#ifndef PKGDIR
#define PKGDIR "var/lib/pacman"
#endif
#ifndef PACCONF
#define PACCONF "/etc/pacman.conf"
#endif
#ifndef CACHEDIR
#define CACHEDIR "var/cache/pacman/pkg"
#endif
/* Operations */ /* Operations */
#define PM_MAIN 1 #define PM_MAIN 1
#define PM_ADD 2 #define PM_ADD 2
@ -49,13 +33,13 @@
#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);
int pacman_deptest(pacdb_t *db, PMList *targets); int pacman_deptest(pacdb_t *db, PMList *targets);
PMList* sortbydeps(PMList *targets); PMList* sortbydeps(PMList *targets, int mode);
PMList* checkdeps(pacdb_t *db, unsigned short op, PMList *targets); PMList* checkdeps(pacdb_t *db, unsigned short op, PMList *targets);
PMList* removedeps(pacdb_t *db, PMList *targs); PMList* removedeps(pacdb_t *db, PMList *targs);
int resolvedeps(pacdb_t *local, PMList *databases, syncpkg_t *sync, PMList *list, PMList *trail); int resolvedeps(pacdb_t *local, PMList *databases, syncpkg_t *sync, PMList *list, PMList *trail);
@ -69,7 +53,6 @@ int parseconfig(char *configfile);
void usage(int op, char *myname); void usage(int op, char *myname);
void version(void); void version(void);
void vprint(char *fmt, ...);
void logaction(FILE *fp, char *fmt, ...); void logaction(FILE *fp, char *fmt, ...);
char* buildstring(PMList *strlist); char* buildstring(PMList *strlist);
int yesno(char* fmt, ...); int yesno(char* fmt, ...);

View file

@ -1,7 +1,7 @@
/* /*
* pacsync.c * pacsync.c
* *
* Copyright (c) 2002-2004 by Judd Vinet <jvinet@zeroflux.org> * Copyright (c) 2002-2006 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
@ -28,12 +28,12 @@
#include <sys/time.h> #include <sys/time.h>
#include <ftplib.h> #include <ftplib.h>
/* pacman */ /* pacman */
#include "pacconf.h"
#include "list.h" #include "list.h"
#include "package.h" #include "package.h"
#include "db.h" #include "db.h"
#include "util.h" #include "util.h"
#include "pacsync.h" #include "pacsync.h"
#include "pacman.h"
/* progress bar */ /* progress bar */
static int log_progress(netbuf *ctl, int xfered, void *arg); static int log_progress(netbuf *ctl, int xfered, void *arg);
@ -52,6 +52,8 @@ extern char *pmo_xfercommand;
extern unsigned short pmo_proxyport; extern unsigned short pmo_proxyport;
extern unsigned short pmo_nopassiveftp; extern unsigned short pmo_nopassiveftp;
extern unsigned short pmo_noprogressbar;
extern unsigned short pmo_chomp;
/* sync servers */ /* sync servers */
extern PMList *pmc_syncs; extern PMList *pmc_syncs;
@ -205,7 +207,7 @@ int downloadfiles_forreal(PMList *servers, const char *localpath,
char *host; char *host;
unsigned port; unsigned port;
host = (pmo_proxyhost) ? pmo_proxyhost : server->server; host = (pmo_proxyhost) ? pmo_proxyhost : server->server;
port = (pmo_proxyhost) ? pmo_proxyport : 80; port = (pmo_proxyport) ? pmo_proxyport : 80;
if(strchr(host, ':')) { if(strchr(host, ':')) {
vprint("connecting to %s\n", host); vprint("connecting to %s\n", host);
} else { } else {
@ -306,7 +308,7 @@ int downloadfiles_forreal(PMList *servers, const char *localpath,
if(ptr && (ptr-fn) < 24) { if(ptr && (ptr-fn) < 24) {
sync_fnm[ptr-fn] = '\0'; sync_fnm[ptr-fn] = '\0';
} }
ptr = strstr(fn, ".pkg.tar.gz"); ptr = strstr(fn, PKGEXT);
if(ptr && (ptr-fn) < 24) { if(ptr && (ptr-fn) < 24) {
sync_fnm[ptr-fn] = '\0'; sync_fnm[ptr-fn] = '\0';
} }
@ -440,6 +442,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");
@ -469,6 +478,15 @@ static int log_progress(netbuf *ctl, int xfered, void *arg)
int i, cur; int i, cur;
struct timeval t1; struct timeval t1;
float timediff; float timediff;
/* a little hard to conceal easter eggs in open-source software, but
* they're still fun. ;)
*/
static unsigned short mouth;
static unsigned int lastcur = 0;
if(pmo_noprogressbar) {
return(1);
}
gettimeofday(&t1, NULL); gettimeofday(&t1, NULL);
if(xfered+offset == fsz) { if(xfered+offset == fsz) {
@ -501,13 +519,39 @@ static int log_progress(netbuf *ctl, int xfered, void *arg)
printf(" %s [", sync_fnm); printf(" %s [", sync_fnm);
cur = (int)((maxcols-64)*pct/100); cur = (int)((maxcols-64)*pct/100);
for(i = 0; i < maxcols-64; i++) { for(i = 0; i < maxcols-64; i++) {
(i < cur) ? printf("#") : printf(" "); if(pmo_chomp) {
if(i < cur) {
printf("-");
} else {
if(i == cur) {
if(lastcur == cur) {
if(mouth) {
printf("\033[1;33mC\033[m");
} else {
printf("\033[1;33mc\033[m");
}
} else {
mouth = mouth == 1 ? 0 : 1;
if(mouth) {
printf("\033[1;33mC\033[m");
} else {
printf("\033[1;33mc\033[m");
}
}
} else {
printf("\033[0;37m*\033[m");
}
}
} else {
(i < cur) ? printf("#") : printf(" ");
}
} }
if(rate > 1000) { if(rate > 1000) {
printf("] %3d%% %6dK %6.0fK/s %02d:%02d:%02d\r", pct, ((xfered+offset) / 1024), rate, eta_h, eta_m, eta_s); printf("] %3d%% %6dK %6.0fK/s %02d:%02d:%02d\r", pct, ((xfered+offset) / 1024), rate, eta_h, eta_m, eta_s);
} else { } else {
printf("] %3d%% %6dK %6.1fK/s %02d:%02d:%02d\r", pct, ((xfered+offset) / 1024), rate, eta_h, eta_m, eta_s); printf("] %3d%% %6dK %6.1fK/s %02d:%02d:%02d\r", pct, ((xfered+offset) / 1024), rate, eta_h, eta_m, eta_s);
} }
lastcur = cur;
fflush(stdout); fflush(stdout);
return(1); return(1);
} }

View file

@ -1,7 +1,7 @@
/* /*
* pacsync.h * pacsync.h
* *
* Copyright (c) 2002-2004 by Judd Vinet <jvinet@zeroflux.org> * Copyright (c) 2002-2006 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

View file

@ -1,7 +1,7 @@
/* /*
* rpmvercmp.c * rpmvercmp.c
* *
* Copyright (c) 2002-2004 by Judd Vinet <jvinet@zeroflux.org> * Copyright (c) 2002-2006 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

View file

@ -1,7 +1,7 @@
/* /*
* rpmvercmp.h * rpmvercmp.h
* *
* Copyright (c) 2002-2004 by Judd Vinet <jvinet@zeroflux.org> * Copyright (c) 2002-2006 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

202
src/strhash.c Normal file
View file

@ -0,0 +1,202 @@
/* evtgen string hash functions.
Copyright (C) 2003 Julien Olivain and LSV, CNRS UMR 8643 & ENS Cachan.
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 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.
*/
/* Copyright (C) 2004 Tommi Rantala <tommi.rantala@cs.helsinki.fi>
*
* Modified for usage in Pacman.
*/
/*
** strhash.c -- string hash utility functions
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "util.h"
#include "list.h"
#include "strhash.h"
void strhash_add_list(strhash_t *hash, PMList* list)
{
for(; list; list = list->next) {
strhash_add(hash, list->data, NULL);
}
}
strhash_t* new_strhash(size_t hsize)
{
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 *));
return(h);
}
void clear_strhash(strhash_t *hash)
{
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 *));
}
void free_strhash(strhash_t *hash)
{
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;
}
}
free(hash->htable);
free(hash);
}
void strhash_add(strhash_t *hash, char *key, char *data)
{
strhash_elmt_t *elmt;
unsigned long hcode;
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++;
}
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, it's not here.
*/
int strhash_isin(strhash_t *hash, char* key)
{
strhash_elmt_t *elmt;
elmt = hash->htable[hash->hash(key) % hash->size];
for(; elmt; elmt = elmt->next) {
if(!strcmp(key, elmt->key)) {
return 1;
}
}
return 0;
}
char* strhash_get(strhash_t *hash, char* key)
{
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;
}
}
return NULL;
}
/*
** fast hash function samples
*/
unsigned long strhash_pjw(char *key)
{
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;
}
}
return (h);
}
int strhash_collide_count(strhash_t *hash)
{
int count;
int i;
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++;
}
}
}
return(count);
}

66
src/strhash.h Normal file
View file

@ -0,0 +1,66 @@
/* evtgen string hash headers.
Copyright (C) 2003 Julien Olivain and LSV, CNRS UMR 8643 & ENS Cachan.
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 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.
*/
/* Copyright (C) 2004 Tommi Rantala <tommi.rantala@cs.helsinki.fi>
*
* Modified for usage in Pacman.
*/
/*
** strhash.h --
*/
#ifndef STRHASH_H
#define STRHASH_H
#define DEFAULT_STRHASH_FUNCTION strhash_pjw
typedef struct strhash_elmt_s strhash_elmt_t;
struct strhash_elmt_s
{
char *key;
char *data;
strhash_elmt_t *next;
};
typedef unsigned long (*strhashfunc_t)(char *key);
typedef struct strhash_s strhash_t;
struct strhash_s
{
strhash_elmt_t **htable;
size_t size;
int elmts;
strhashfunc_t hash;
};
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);
int strhash_collide_count(strhash_t *hash);
unsigned long strhash_pjw(char *key);
#endif /* STRHASH_H */

View file

@ -1,7 +1,7 @@
/* /*
* util.c * util.c
* *
* Copyright (c) 2002-2004 by Judd Vinet <jvinet@zeroflux.org> * Copyright (c) 2002-2006 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
@ -30,8 +30,25 @@
#include <dirent.h> #include <dirent.h>
#include <zlib.h> #include <zlib.h>
#include <libtar.h> #include <libtar.h>
#include <regex.h>
#include "util.h" #include "util.h"
extern unsigned short pmo_verbose;
/* Check verbosity option and, if set, print the
* string to stdout
*/
void vprint(char *fmt, ...)
{
va_list args;
if(pmo_verbose) {
va_start(args, fmt);
vprintf(fmt, args);
va_end(args);
fflush(stdout);
}
}
/* borrowed and modified from Per Liden's pkgutils (http://crux.nu) */ /* borrowed and modified from Per Liden's pkgutils (http://crux.nu) */
long gzopen_frontend(char *pathname, int oflags, int mode) long gzopen_frontend(char *pathname, int oflags, int mode)
{ {
@ -203,6 +220,103 @@ int rmrf(char *path)
return(0); return(0);
} }
/* Convert a relative path to an absolute path
*
* This function was taken from the pathconvert library and massaged
* to match our coding style. The pathconvert version is
* Copyright (c) 1997 Shigio Yamaguchi.
*/
char *rel2abs(const char *path, char *result, const size_t size)
{
const char *pp, *bp;
/* endp points the last position which is safe in the result buffer. */
const char *endp = result + size - 1;
char *rp;
int length;
char base[PATH_MAX+1];
getcwd(base, PATH_MAX);
if(*path == '/') {
if(strlen(path) >= size) {
goto erange;
}
strcpy(result, path);
goto finish;
} else if(*base != '/' || !size) {
errno = EINVAL;
return (NULL);
} else if(size == 1) {
goto erange;
}
length = strlen(base);
if(!strcmp(path, ".") || !strcmp(path, "./")) {
if(length >= size) {
goto erange;
}
strcpy(result, base);
/* rp points the last char. */
rp = result + length - 1;
/* remove the last '/'. */
if(*rp == '/') {
if(length > 1) {
*rp = 0;
}
} else {
rp++;
}
/* rp point NULL char */
if(*++path == '/') {
/* Append '/' to the tail of path name. */
*rp++ = '/';
if(rp > endp) {
goto erange;
}
*rp = 0;
}
goto finish;
}
bp = base + length;
if(*(bp - 1) == '/') {
--bp;
}
/* up to root. */
for(pp = path; *pp && *pp == '.'; ) {
if(!strncmp(pp, "../", 3)) {
pp += 3;
while(bp > base && *--bp != '/');
} else if(!strncmp(pp, "./", 2)) {
pp += 2;
} else if(!strncmp(pp, "..\0", 3)) {
pp += 2;
while(bp > base && *--bp != '/');
} else {
break;
}
}
/* down to leaf. */
length = bp - base;
if(length >= size) {
goto erange;
}
strncpy(result, base, length);
rp = result + length;
if(*pp || *(pp - 1) == '/' || length == 0) {
*rp++ = '/';
}
if(rp + strlen(pp) > endp) {
goto erange;
}
strcpy(rp, pp);
finish:
return result;
erange:
errno = ERANGE;
return (NULL);
}
/* output a string, but wrap words properly with a specified indentation /* output a string, but wrap words properly with a specified indentation
*/ */
void indentprint(char *str, int indent) void indentprint(char *str, int indent)
@ -265,6 +379,11 @@ char* strtoupper(char *str)
char* trim(char *str) char* trim(char *str)
{ {
char *pch = str; char *pch = str;
if(*str == '\0')
/* string is empty, so we're done. */
return(str);
while(isspace(*pch)) { while(isspace(*pch)) {
pch++; pch++;
} }
@ -272,13 +391,18 @@ char* trim(char *str)
memmove(str, pch, (strlen(pch) + 1)); memmove(str, pch, (strlen(pch) + 1));
} }
/* check if there wasn't anything but whitespace in the string. */
if(*str == '\0') {
return(str);
}
pch = (char*)(str + (strlen(str) - 1)); pch = (char*)(str + (strlen(str) - 1));
while(isspace(*pch)) { while(isspace(*pch)) {
pch--; pch--;
} }
*++pch = '\0'; *++pch = '\0';
return str; return(str);
} }
/* A cheap grep for text files, returns 1 if a substring /* A cheap grep for text files, returns 1 if a substring
@ -304,5 +428,19 @@ int grep(const char *fn, const char *needle)
return(0); return(0);
} }
int reg_match(char *string, char *pattern)
{
int result;
regex_t reg;
if (regcomp(&reg, pattern, REG_EXTENDED | REG_NOSUB | REG_ICASE) != 0)
{
fprintf(stderr, "error: %s is not a valid regular expression.\n", pattern);
exit(1);
}
result = regexec(&reg, string, 0, 0, 0);
regfree(&reg);
return(!(result));
}
/* vim: set ts=2 sw=2 noet: */ /* vim: set ts=2 sw=2 noet: */

View file

@ -1,7 +1,7 @@
/* /*
* util.h * util.h
* *
* Copyright (c) 2002-2004 by Judd Vinet <jvinet@zeroflux.org> * Copyright (c) 2002-2006 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
@ -28,15 +28,18 @@
#define FREE(p) { if (p) { free(p); (p)= NULL; }} #define FREE(p) { if (p) { free(p); (p)= NULL; }}
void vprint(char *fmt, ...);
long gzopen_frontend(char *pathname, int oflags, int mode); long gzopen_frontend(char *pathname, int oflags, int mode);
int unpack(char *archive, const char *prefix, const char *fn); int unpack(char *archive, const char *prefix, const char *fn);
int copyfile(char *src, char *dest); int copyfile(char *src, char *dest);
int makepath(char *path); int makepath(char *path);
int rmrf(char *path); int rmrf(char *path);
char *rel2abs(const char *path, char *result, const size_t size);
void indentprint(char *str, int indent); void indentprint(char *str, int indent);
char* trim(char *str); char* trim(char *str);
char* strtoupper(char *str); char* strtoupper(char *str);
int grep(const char *fn, const char *needle); int grep(const char *fn, const char *needle);
int reg_match(char *string, char *pattern);
#endif #endif
/* vim: set ts=2 sw=2 noet: */ /* vim: set ts=2 sw=2 noet: */

View file

@ -1,7 +1,7 @@
/* /*
* vercmp.c * vercmp.c
* *
* Copyright (c) 2002-2004 by Judd Vinet <jvinet@zeroflux.org> * Copyright (c) 2002-2006 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