summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJudd Vinet <judd@archlinux.org>2003-05-30 21:56:46 +0200
committerJudd Vinet <judd@archlinux.org>2003-05-30 21:56:46 +0200
commit636c6411196ba415652ea3357c781cbe62afea6b (patch)
treed955b454a0e22faec330725758b03fb4186f079e
parente9c6f3b2131217acb4191ed69bfc3f6efa53dfbf (diff)
downloadpacman-636c6411196ba415652ea3357c781cbe62afea6b.tar.gz
pacman-636c6411196ba415652ea3357c781cbe62afea6b.tar.xz
Imported from pacman-2.5.tar.gz
-rw-r--r--ChangeLog10
-rw-r--r--Makefile.in21
-rwxr-xr-xcnvpkg19
-rw-r--r--doc/makepkg.8.in44
-rw-r--r--doc/pacman.8.in96
-rwxr-xr-xscripts/gensync2
-rwxr-xr-xscripts/makepkg500
-rwxr-xr-xscripts/makeworld8
-rw-r--r--src/convertdb.c24
-rw-r--r--src/db.c81
-rw-r--r--src/db.h5
-rw-r--r--src/list.c94
-rw-r--r--src/list.h24
-rw-r--r--src/md5.h3
-rw-r--r--src/md5driver.c3
-rw-r--r--src/package.c129
-rw-r--r--src/package.h5
-rw-r--r--src/pacman.c696
-rw-r--r--src/pacman.h12
-rw-r--r--src/pacsync.c40
-rw-r--r--src/pacsync.h3
-rw-r--r--src/rpmvercmp.h28
-rw-r--r--src/util.c491
-rw-r--r--src/util.h14
-rw-r--r--src/vercmp.c24
25 files changed, 1270 insertions, 1106 deletions
diff --git a/ChangeLog b/ChangeLog
index eb5428e8..b56da5b5 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,15 @@
VERSION DESCRIPTION
------------------------------------------------------------------
+2.5 - Added an URL tag to package info
+ - Sped up package load times by about 500% by introducing
+ a .FILELIST into the package
+ - Renamed the install scriptlet from ._install to .INSTALL
+ - Added patch from Aurlien Foret:
+ - Better lock handling (RW and RO)
+ - Sorted package order in -Qi's dependency lists
+ - Added a DBPath option to pacman.conf
+ - Fixed memory leaks
+ - Added the --nodeps option to -S
2.4.1 - Fixed a bug in makepkg's option parsing
2.4 - Added getopt-style options to makeworld
- Added -w <destdir> to makepkg
diff --git a/Makefile.in b/Makefile.in
index 85e0a627..9036f1a2 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -34,7 +34,7 @@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
INSTALL_DATA = @INSTALL_DATA@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
-PACVER = 2.4.1
+PACVER = 2.5
TOPDIR = @srcdir@
SRCDIR = $(TOPDIR)/src/
@@ -43,7 +43,7 @@ MANSRC = $(TOPDIR)/doc/
SCRDIR = $(TOPDIR)/scripts/
CXX = @CC@
-CXXFLAGS += @CFLAGS@ -g -Wall -pedantic -fno-exceptions -fno-rtti \
+CXXFLAGS += @CFLAGS@ -g -Wall -pedantic -fno-exceptions \
-D_GNU_SOURCE -DPACVER=\"$(PACVER)\" -I. -Ilibftp
LDFLAGS += @LDFLAGS@ -static -Llibftp -lftp -ltar -lz
@@ -53,9 +53,10 @@ SRCS = $(SRCDIR)pacman.c \
$(SRCDIR)list.c \
$(SRCDIR)package.c \
$(SRCDIR)pacsync.c \
- $(SRCDIR)rpmvercmp.c \
$(SRCDIR)md5.c \
- $(SRCDIR)md5driver.c
+ $(SRCDIR)md5driver.c \
+ $(SRCDIR)vercmp.c \
+ $(SRCDIR)rpmvercmp.c
OBJECTS = $(OBJDIR)pacman.o \
$(OBJDIR)db.o \
@@ -63,20 +64,20 @@ OBJECTS = $(OBJDIR)pacman.o \
$(OBJDIR)list.o \
$(OBJDIR)package.o \
$(OBJDIR)pacsync.o \
- $(OBJDIR)rpmvercmp.o \
$(OBJDIR)md5.o \
- $(OBJDIR)md5driver.o
+ $(OBJDIR)md5driver.o \
+ $(OBJDIR)rpmvercmp.o
all: ftplib pacman vercmp convertdb man
pacman: $(OBJECTS)
$(CXX) $(OBJECTS) -o $@ $(LDFLAGS)
-vercmp: $(OBJDIR)rpmvercmp.o $(OBJDIR)vercmp.o
- $(CXX) $(OBJDIR)rpmvercmp.o $(OBJDIR)vercmp.o -o $@
+vercmp: $(OBJDIR)vercmp.o $(OBJDIR)rpmvercmp.o
+ $(CXX) $(OBJDIR)vercmp.o $(OBJDIR)rpmvercmp.o $(CXXFLAGS) -o $@
-convertdb: $(SRCDIR)convertdb.c $(SRCDIR)list.c
- $(CXX) -o convertdb $(SRCDIR)convertdb.c $(SRCDIR)list.c $(CXXFLAGS)
+convertdb: $(OBJDIR)convertdb.o $(OBJDIR)list.o $(OBJDIR)util.o
+ $(CXX) $(OBJDIR)convertdb.o $(OBJDIR)list.o $(OBJDIR)util.o $(CXXFLAGS) -lz -ltar -o $@
.c.o: $(SRCS)
$(CXX) $(CXXFLAGS) -o $@ -c $<
diff --git a/cnvpkg b/cnvpkg
new file mode 100755
index 00000000..2a164c12
--- /dev/null
+++ b/cnvpkg
@@ -0,0 +1,19 @@
+#!/bin/bash
+
+TMPDIR=/tmp/.pkgcnv
+TMPFILE=/tmp/.pkgcnvf
+tl=`pwd`
+
+for fn in $*; do
+ rm -rf $TMPDIR;
+ mkdir -p $TMPDIR;
+ echo "Converting $fn"
+ cd $TMPDIR
+ tar zxvf $tl/$fn | grep -v '^.PKGINFO' | grep -v '._install' >$TMPFILE
+ mv $TMPFILE ./.FILELIST
+ if [ -f ._install ]; then
+ tar cfz /new/$fn .PKGINFO .FILELIST ._install *
+ else
+ tar cfz /new/$fn .PKGINFO .FILELIST *
+ fi
+done
diff --git a/doc/makepkg.8.in b/doc/makepkg.8.in
index 8d8f8437..d6a7994f 100644
--- a/doc/makepkg.8.in
+++ b/doc/makepkg.8.in
@@ -1,4 +1,4 @@
-.TH makepkg 8 "April 19, 2003" "makepkg #VERSION#" ""
+.TH makepkg 8 "May 27, 2003" "makepkg #VERSION#" ""
.SH NAME
makepkg \- package build utility
.SH SYNOPSIS
@@ -34,6 +34,7 @@ pkgname=modutils
pkgver=2.4.13
pkgrel=1
pkgdesc="Utilities for inserting and removing modules from the linux kernel"
+url="http://www.kernel.org"
backup=(etc/modules.conf)
depends=('glibc>=2.2.5' 'bash' 'zlib')
source=(ftp://ftp.server.com/$pkgname-$pkgver.tar.gz modules.conf)
@@ -187,6 +188,11 @@ This is the release number specific to Arch Linux packages.
This should be a brief description of the package and its functionality.
.TP
+.B url
+This field contains an optional URL that is associated with the piece of software
+being packaged. This is typically the project's website.
+
+.TP
.B backup
A space-delimited array of filenames (without a preceding slash). The
\fIbackup\fP line will be propagated to the package meta-info file for
@@ -226,21 +232,6 @@ by wget.
.SH MAKEPKG OPTIONS
.TP
-.B "\-c, \-\-clean"
-Clean up leftover work files/directories after a successful build.
-.TP
-.B "\-C, \-\-cleancache"
-Removes all source files from the cache directory to free up diskspace.
-.TP
-.B "\-i, \-\-install"
-Install/Upgrade the package after a successful build.
-.TP
-.B "\-s, \-\-syncdeps"
-Install missing dependencies using pacman. When makepkg finds missing
-dependencies, it will run pacman to try and resolve them. If successful,
-pacman will download the missing packages from a package repository and
-install them for you.
-.TP
.B "\-b, \-\-builddeps"
Build missing dependencies from source. When makepkg finds missing
dependencies, it will look for the dependencies' PKGBUILD files under
@@ -248,6 +239,12 @@ $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.
The child makepkg calls will be made with the \fB-b\fP and \fB-i\fP options.
.TP
+.B "\-c, \-\-clean"
+Clean up leftover work files/directories after a successful build.
+.TP
+.B "\-C, \-\-cleancache"
+Removes all source files from the cache directory to free up diskspace.
+.TP
.B "\-d, \-\-nodeps"
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
@@ -258,12 +255,21 @@ process if all of the dependencies aren't installed.
file already exists in the build directory. You can override this behaviour with
the \fB--force\fP switch.
.TP
-.B "\-w <destdir>"
-Write the resulting package file to the directory \fI<destdir>\fP instead of the
-current working directory.
+.B "\-i, \-\-install"
+Install/Upgrade the package after a successful build.
.TP
.B "\-p <buildscript>"
Read the package script \fI<buildscript>\fP instead of the default (\fIPKGBUILD\fP).
+.TP
+.B "\-s, \-\-syncdeps"
+Install missing dependencies using pacman. When makepkg finds missing
+dependencies, it will run pacman to try and resolve them. If successful,
+pacman will download the missing packages from a package repository and
+install them for you.
+.TP
+.B "\-w <destdir>"
+Write the resulting package file to the directory \fI<destdir>\fP instead of the
+current working directory.
.SH CONFIGURATION
Configuration options are stored in \fI/etc/makepkg.conf\fP. This file is parsed
diff --git a/doc/pacman.8.in b/doc/pacman.8.in
index ce9e699c..2113fc21 100644
--- a/doc/pacman.8.in
+++ b/doc/pacman.8.in
@@ -1,4 +1,4 @@
-.TH pacman 8 "April 10, 2003" "pacman #VERSION#" ""
+.TH pacman 8 "May 27, 2003" "pacman #VERSION#" ""
.SH NAME
pacman \- package manager utility
.SH SYNOPSIS
@@ -14,18 +14,6 @@ the local system. pacman package are \fIgzipped tar\fP format.
Add a package to the system. Package will be uncompressed
into the installation root and the database will be updated.
.TP
-.B "\-R, \-\-remove"
-Remove a package from the system. Files belonging to the
-specified package will be deleted, and the database will
-be updated. Most configuration files will be saved with a
-\fI.pacsave\fP extension unless the \fB--nosave\fP option was
-used.
-.TP
-.B "\-U, \-\-upgrade"
-Upgrade a package. This is essentially a "remove-then-add"
-process. See \fBHANDLING CONFIG FILES\fP for an explanation
-on how pacman takes care of config files.
-.TP
.B "\-F, \-\-freshen"
This is like --upgrade except that, unlike --upgrade, this will only
upgrade packages that are already installed on your system.
@@ -38,6 +26,13 @@ build date, size). This can be run against the local package
database or can be used on individual .tar.gz packages. See
\fBQUERY OPTIONS\fP below.
.TP
+.B "\-R, \-\-remove"
+Remove a package from the system. Files belonging to the
+specified package will be deleted, and the database will
+be updated. Most configuration files will be saved with a
+\fI.pacsave\fP extension unless the \fB--nosave\fP option was
+used.
+.TP
.B "\-S, \-\-sync"
Synchronize packages. With this function you can install packages
directly from the ftp servers, complete with all dependencies required
@@ -45,6 +40,11 @@ to run the packages. For example, \fBpacman -S qt\fP will download
qt and all the packages it depends on and install them. You could also use
\fBpacman -Su\fP to upgrade all packages that are out of date (see below).
.TP
+.B "\-U, \-\-upgrade"
+Upgrade a package. This is essentially a "remove-then-add"
+process. See \fBHANDLING CONFIG FILES\fP for an explanation
+on how pacman takes care of config files.
+.TP
.B "\-V, \-\-version"
Display version and exit.
.TP
@@ -53,14 +53,10 @@ Display syntax for the given operation. If no operation was
supplied then the general syntax is shown.
.SH OPTIONS
.TP
-.B "\-v, \-\-verbose"
-Output more status and error messages.
-.TP
-.B "\-f, \-\-force"
-Bypass file conflict checks,, overwriting conflicting files. If the
-package that is about to be installed contains files that are already
-installed, this option will cause all those files to be overwritten.
-This option should be used with care, ideally not at all.
+.B "\-c, \-\-cascade"
+(only used with \fB--remove\fP)
+Remove all target packages, as well as all packages that depend on one
+or more target packages. This operation is recursive.
.TP
.B "\-d, \-\-nodeps"
Skips all dependency checks. Normally, pacman will always check
@@ -68,6 +64,12 @@ a package's dependency fields to ensure that all dependencies are
installed and there are no package conflicts in the system. This
switch disables these checks.
.TP
+.B "\-f, \-\-force"
+Bypass file conflict checks,, overwriting conflicting files. If the
+package that is about to be installed contains files that are already
+installed, this option will cause all those files to be overwritten.
+This option should be used with care, ideally not at all.
+.TP
.B "\-n, \-\-nosave"
(only used with \fB--remove\fP)
Instructs pacman to ignore file backup designations. Normally, when
@@ -76,11 +78,6 @@ checked to see if the file should be renamed to a .pacsave extension. If
\fB--nosave\fP is used, these designations are ignored and the files are
removed.
.TP
-.B "\-c, \-\-cascade"
-(only used with \fB--remove\fP)
-Remove all target packages, as well as all packages that depend on one
-or more target packages. This operation is recursive.
-.TP
.B "\-r, \-\-root <path>"
Specify alternative installation root (default is "/"). This
should \fInot\fP be used as a way to install software into
@@ -89,12 +86,19 @@ if you want to install a package on a temporary mounted partition,
which is "owned" by another system. By using this option you not only
specify where the software should be installed, but you also
specify which package database to use.
+.TP
+.B "\-v, \-\-verbose"
+Output more status and error messages.
.SH SYNC OPTIONS
.TP
-.B "\-y, \-\-refresh"
-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
-time you use \fB--sysupgrade\fP.
+.B "\-c, \-\-clean"
+Remove packages from the cache. When pacman downloads packages,
+it saves them in \fI/var/cache/pacman/pkg\fP. If you need to free up
+diskspace, you can remove these packages by using the --clean option.
+.TP
+.B "\-s, \-\-search <string>"
+This will search each package in the package list for names or descriptions
+that contains <string>.
.TP
.B "\-u, \-\-sysupgrade"
Upgrades all packages that are out of date. pacman will examine every
@@ -104,29 +108,25 @@ it wants to upgrade and will not proceed without user confirmation.
Dependencies are automatically resolved at this level and will be
installed/upgraded if necessary.
.TP
-.B "\-s, \-\-search <string>"
-This will search each package in the package list for names or descriptions
-that contains <string>.
-.TP
.B "\-w, \-\-downloadonly"
Retrieve all packages from the server, but do not install/upgrade anything.
.TP
-.B "\-c, \-\-clean"
-Remove packages from the cache. When pacman downloads packages,
-it saves them in \fI/var/cache/pacman/pkg\fP. If you need to free up
-diskspace, you can remove these packages by using the --clean option.
+.B "\-y, \-\-refresh"
+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
+time you use \fB--sysupgrade\fP.
.SH QUERY OPTIONS
.TP
-.B "\-o, \-\-owns <file>"
-Search for the package that owns <file>.
+.B "\-i, \-\-info"
+Display information on a given package. If it is used with the \fB-p\fP
+option then the .PKGINFO file will be printed.
.TP
.B "\-l, \-\-list"
List all files owned by <package>. Multiple packages can be specified on
the command line.
.TP
-.B "\-i, \-\-info"
-Display information on a given package. If it is used with the \fB-p\fP
-option then the .PKGINFO file will be printed.
+.B "\-o, \-\-owns <file>"
+Search for the package that owns <file>.
.TP
.B "\-p, \-\-file"
Tells pacman that the package supplied on the command line is a
@@ -185,9 +185,9 @@ Server = local:///home/pkgs
.RE
.SH CONFIG: OPTIONS
.TP
-.B "NoUpgrade = <file> [file] ..."
-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.
+.B "DBPath = /path/to/db/dir"
+Overrides the default location of the toplevel database directory. The default is
+\fI/var/lib/pacman\fP.
.TP
.B "IgnorePkg = <package> [package] ..."
Instructs pacman to ignore any upgrades for this package when performing a
@@ -195,6 +195,10 @@ Instructs pacman to ignore any upgrades for this package when performing a
.TP
.B "NoPassiveFtp"
Disables passive ftp connections when downloading packages. (aka Active Mode)
+.TP
+.B "NoUpgrade = <file> [file] ..."
+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.
.SH CONFIG: REPOSITORIES
Each repository section defines a section name and at least one location where the packages
diff --git a/scripts/gensync b/scripts/gensync
index 8a87d8f1..769972a6 100755
--- a/scripts/gensync
+++ b/scripts/gensync
@@ -1,6 +1,6 @@
#!/bin/bash
-myver='2.4.1'
+myver='2.5'
usage() {
echo "gensync $myver"
diff --git a/scripts/makepkg b/scripts/makepkg
index b55ef576..08cddb38 100755
--- a/scripts/makepkg
+++ b/scripts/makepkg
@@ -1,12 +1,12 @@
#!/bin/bash
-myver='2.4.1'
+myver='2.5'
startdir=`pwd`
[ -f /etc/makepkg.conf ] && source /etc/makepkg.conf
strip_url() {
- echo $1 | sed 's|^.*://.*/||g'
+ echo $1 | sed 's|^.*://.*/||g'
}
msg() {
@@ -14,57 +14,57 @@ msg() {
}
checkdeps() {
- local missdep=`pacman -T $*`
+ local missdep=`pacman -T $*`
local deplist=""
missdep=`pacman -T $*`
- ret=$?
- if [ "$ret" != "0" ]; then
- if [ "$ret" = "127" ]; then
- msg "==> Missing Dependencies:"
- msg ""
- nl=0
- for dep in $missdep; do
- echo -ne "$dep " >&2
- if [ "$nl" = "1" ]; then
- nl=0
- echo -ne "\n" >&2
- # add this dep to the list
- depname=`echo $dep | sed 's|=.*$||' | sed 's|>.*$||' | sed 's|<.*$||'`
- deplist="$deplist $depname"
- continue
- fi
- nl=1
- done
- msg ""
- else
- msg "==> ERROR: pacman returned a fatal error."
- exit 1
- fi
- fi
+ ret=$?
+ if [ "$ret" != "0" ]; then
+ if [ "$ret" = "127" ]; then
+ msg "==> Missing Dependencies:"
+ msg ""
+ nl=0
+ for dep in $missdep; do
+ echo -ne "$dep " >&2
+ if [ "$nl" = "1" ]; then
+ nl=0
+ echo -ne "\n" >&2
+ # add this dep to the list
+ depname=`echo $dep | sed 's|=.*$||' | sed 's|>.*$||' | sed 's|<.*$||'`
+ deplist="$deplist $depname"
+ continue
+ fi
+ nl=1
+ done
+ msg ""
+ else
+ msg "==> ERROR: pacman returned a fatal error."
+ exit 1
+ fi
+ fi
echo $deplist
}
usage() {
- echo "makepkg version $myver"
- echo "usage: $0 [options]"
- echo "options:"
- echo " -c, --clean Clean up work files after build"
- echo " -C, --cleancache Clean up source files from the cache"
- echo " -s, --syncdeps Install missing dependencies with pacman"
- echo " -b, --builddeps Build missing dependencies from source"
- echo " -d, --nodeps Skip all dependency checks"
- echo " -i, --install Install package after successful build"
- echo " -f, --force Overwrite existing package"
- echo " -w <destdir> Write package to <destdir> instead of the working dir"
- echo " -p <buildscript> Use an alternate build script (instead of PKGBUILD)"
- echo " -h, --help This help"
- echo
- echo " if build_script is not specified, makepkg will look for a PKGBUILD"
- echo " file in the current directory."
- echo
- exit 0
+ echo "makepkg version $myver"
+ echo "usage: $0 [options]"
+ echo "options:"
+ echo " -c, --clean Clean up work files after build"
+ echo " -C, --cleancache Clean up source files from the cache"
+ echo " -s, --syncdeps Install missing dependencies with pacman"
+ echo " -b, --builddeps Build missing dependencies from source"
+ echo " -d, --nodeps Skip all dependency checks"
+ echo " -i, --install Install package after successful build"
+ echo " -f, --force Overwrite existing package"
+ echo " -w <destdir> Write package to <destdir> instead of the working dir"
+ echo " -p <buildscript> Use an alternate build script (instead of PKGBUILD)"
+ echo " -h, --help This help"
+ echo
+ echo " if -p is not specified, makepkg will look for a PKGBUILD"
+ echo " file in the current directory."
+ echo
+ exit 0
}
# Options
@@ -79,139 +79,135 @@ PKGDEST=$startdir
BUILDSCRIPT="./PKGBUILD"
while [ "$#" -ne "0" ]; do
- case $1 in
- --clean) CLEANUP=1 ;;
- --cleancache) CLEANCACHE=1 ;;
- --syncdeps) DEP_BIN=1 ;;
- --builddeps) DEP_SRC=1 ;;
- --nodeps) NODEPS=1 ;;
- --install) INSTALL=1 ;;
- --force) FORCE=1 ;;
- --*)
- usage
- exit 1
- ;;
- -*)
- while getopts "cCsbdifp:w:-" opt; do
- case $opt in
- c) CLEANUP=1 ;;
- C) CLEANCACHE=1 ;;
- s) DEP_BIN=1 ;;
- b) DEP_SRC=1 ;;
- d) NODEPS=1 ;;
- i) INSTALL=1 ;;
- f) FORCE=1 ;;
- w)
- PKGDEST=$OPTARG
- ;;
- p)
- BUILDSCRIPT=$OPTARG
- ;;
- -)
- OPTIND=0
- break
- ;;
- *)
- usage
- exit 1
- ;;
- esac
- done
- ;;
- *)
- true
- ;;
- esac
- shift
+ case $1 in
+ --clean) CLEANUP=1 ;;
+ --cleancache) CLEANCACHE=1 ;;
+ --syncdeps) DEP_BIN=1 ;;
+ --builddeps) DEP_SRC=1 ;;
+ --nodeps) NODEPS=1 ;;
+ --install) INSTALL=1 ;;
+ --force) FORCE=1 ;;
+ --*)
+ usage
+ exit 1
+ ;;
+ -*)
+ while getopts "cCsbdifp:w:-" opt; do
+ case $opt in
+ c) CLEANUP=1 ;;
+ C) CLEANCACHE=1 ;;
+ s) DEP_BIN=1 ;;
+ b) DEP_SRC=1 ;;
+ d) NODEPS=1 ;;
+ i) INSTALL=1 ;;
+ f) FORCE=1 ;;
+ w) PKGDEST=$OPTARG ;;
+ p) BUILDSCRIPT=$OPTARG ;;
+ -)
+ OPTIND=0
+ break
+ ;;
+ *)
+ usage
+ exit 1
+ ;;
+ esac
+ done
+ ;;
+ *)
+ true
+ ;;
+ esac
+ shift
done
if [ "$CLEANCACHE" = "1" ]; then
- msg "==> Cleaning up source files from the cache"
- rm -rf /var/cache/pacman/src/*
- exit 0
+ msg "==> Cleaning up source files from the cache"
+ rm -rf /var/cache/pacman/src/*
+ exit 0
fi
-unset pkgname pkgver pkgrel pkgdesc
+unset pkgname pkgver pkgrel pkgdesc url
unset depends conflicts backup source install build
umask 0022
if [ ! -f $BUILDSCRIPT ]; then
- msg "==> ERROR: $BUILDSCRIPT does not exist."
- exit 1
+ msg "==> ERROR: $BUILDSCRIPT does not exist."
+ exit 1
fi
source $BUILDSCRIPT
# check for no-no's
if [ `echo $pkgver | grep '-'` ]; then
- msg "==> ERROR: pkgver is not allowed to contain hyphens."
- exit 1
+ msg "==> ERROR: pkgver is not allowed to contain hyphens."
+ exit 1
fi
if [ `echo $pkgrel | grep '-'` ]; then
- msg "==> ERROR: pkgrel is not allowed to contain hyphens."
- exit 1
+ msg "==> ERROR: pkgrel is not allowed to contain hyphens."
+ exit 1
fi
if [ -f $PKGDEST/${pkgname}-${pkgver}-${pkgrel}.pkg.tar.gz -a "$FORCE" = "0" ]; then
- msg "==> ERROR: a package has already been built. (use -f to overwrite)"
- exit 1
+ msg "==> ERROR: a package has already been built. (use -f to overwrite)"
+ exit 1
fi
unset deplist
if [ `type -p pacman` -a "$NODEPS" = "0" ]; then
- msg "==> Checking Dependencies..."
+ msg "==> Checking Dependencies..."
deplist=`checkdeps ${depends[@]}`
- if [ "$deplist" != "" ]; then
- if [ "$DEP_BIN" = "1" ]; then
- # install missing deps from binary packages (using pacman -S)
- msg "==> Installing missing dependencies..."
- pacman -D $deplist
- if [ "$?" = "127" ]; then
- msg "==> ERROR: Failed to install missing dependencies."
- exit 1
- fi
- # TODO: check deps again to make sure they were resolved
- elif [ "$DEP_SRC" = "1" ]; then
- # install missing deps by building them from source.
- # we look for each package name in $ABSROOT and build it.
- if [ "$ABSROOT" = "" ]; then
- msg "==> ERROR: The ABSROOT environment variable is not defined."
- exit 1
- fi
- # TODO: handle version comparators (eg, glibc>=2.2.5)
- msg "==> Building missing dependencies..."
- for dep in $deplist; do
- candidates=`find $ABSROOT -type d -name "$dep"`
- if [ "$candidates" = "" ]; then
- msg "==> ERROR: Could not find \"$dep\" under $ABSROOT"
- exit 1
- fi
- success=0
- for pkgdir in $candidates; do
- if [ -f $pkgdir/PKGBUILD ]; then
- cd $pkgdir
- echo makepkg -i -c -b -w $PKGDEST
- makepkg -i -c -b -w $PKGDEST
- if [ $? -eq 0 ]; then
- success=1
- break
- fi
- fi
- done
- if [ "$success" = "0" ]; then
- msg "==> ERROR: Failed to build \"$dep\""
- exit 1
- fi
- done
- # TODO: check deps again to make sure they were resolved
- else
- exit 1
- fi
- fi
+ if [ "$deplist" != "" ]; then
+ if [ "$DEP_BIN" = "1" ]; then
+ # install missing deps from binary packages (using pacman -S)
+ msg "==> Installing missing dependencies..."
+ pacman -D $deplist
+ if [ "$?" = "127" ]; then
+ msg "==> ERROR: Failed to install missing dependencies."
+ exit 1
+ fi
+ # TODO: check deps again to make sure they were resolved
+ elif [ "$DEP_SRC" = "1" ]; then
+ # install missing deps by building them from source.
+ # we look for each package name in $ABSROOT and build it.
+ if [ "$ABSROOT" = "" ]; then
+ msg "==> ERROR: The ABSROOT environment variable is not defined."
+ exit 1
+ fi
+ # TODO: handle version comparators (eg, glibc>=2.2.5)
+ msg "==> Building missing dependencies..."
+ for dep in $deplist; do
+ candidates=`find $ABSROOT -type d -name "$dep"`
+ if [ "$candidates" = "" ]; then
+ msg "==> ERROR: Could not find \"$dep\" under $ABSROOT"
+ exit 1
+ fi
+ success=0
+ for pkgdir in $candidates; do
+ if [ -f $pkgdir/PKGBUILD ]; then
+ cd $pkgdir
+ echo makepkg -i -c -b -w $PKGDEST
+ makepkg -i -c -b -w $PKGDEST
+ if [ $? -eq 0 ]; then
+ success=1
+ break
+ fi
+ fi
+ done
+ if [ "$success" = "0" ]; then
+ msg "==> ERROR: Failed to build \"$dep\""
+ exit 1
+ fi
+ done
+ # TODO: check deps again to make sure they were resolved
+ else
+ exit 1
+ fi
+ fi
elif [ "$NODEPS" = "1" ]; then
- msg "==> WARNING: skipping dependency checks."
+ msg "==> WARNING: skipping dependency checks."
else
- msg "==> WARNING: pacman was not found in PATH. skipping dependency checks."
+ msg "==> WARNING: pacman was not found in PATH. skipping dependency checks."
fi
d=`date`
@@ -223,69 +219,69 @@ msg "==> Acquiring/Extracting Sources..."
mkdir -p src
cd $startdir/src
for netfile in ${source[@]}; do
- file=`strip_url $netfile`
- if [ -f ../$file ]; then
- msg "==> Found $file in build dir"
- cp ../$file .
- elif [ -f /var/cache/pacman/src/$file ]; then
- msg "==> Using local copy of $file"
- cp /var/cache/pacman/src/$file .
- else
- # check for a download utility
- if [ -z "$FTPAGENT" ]; then
- msg "==> ERROR: FTPAGENT is not configured. Check the /etc/makepkg.conf file."
- msg "==> Aborting..."
- exit 1
- fi
- ftpclient=`echo $FTPAGENT | awk {'print $1'}`
- if [ ! -x $ftpclient ]; then
- msg "==> ERROR: ftpclient `basename $ftpclient` is not installed."
- msg "==> Aborting..."
- exit 1
- fi
- proto=`echo $netfile | sed 's|://.*||'`
- if [ "$proto" != "ftp" -a "$proto" != "http" ]; then
- msg "==> ERROR: $netfile was not found in the build directory and is not a proper URL."
- msg "==> Aborting..."
- exit 1
- fi
- msg "==> Downloading $file"
- $FTPAGENT $netfile 2>&1
- if [ ! -f $file ]; then
- msg "==> ERROR: Failed to download $file"
- msg "==> Aborting..."
- exit 1
- fi
- mkdir -p /var/cache/pacman/src && cp $file /var/cache/pacman/src
- fi
- unset cmd
- case $file in
- *.tar.gz|*.tar.Z|*.tgz)
- cmd="tar --use-compress-program=gzip -xf $file" ;;
- *.tar.bz2)
- cmd="tar --use-compress-program=bzip2 -xf $file" ;;
- *.tar)
- cmd="tar -xf $file" ;;
- *.zip)
- cmd="unzip -qq $file" ;;
- *.gz)
- cmd="gunzip $file" ;;
- esac
- if [ "$cmd" != "" ]; then
- msg "==> $cmd"
- $cmd
- if [ $? -ne 0 ]; then
- msg "==> ERROR: Failed to extract $file"
- msg "==> Aborting..."
- exit 1
- fi
- fi
+ file=`strip_url $netfile`
+ if [ -f ../$file ]; then
+ msg "==> Found $file in build dir"
+ cp ../$file .
+ elif [ -f /var/cache/pacman/src/$file ]; then
+ msg "==> Using local copy of $file"
+ cp /var/cache/pacman/src/$file .
+ else
+ # check for a download utility
+ if [ -z "$FTPAGENT" ]; then
+ msg "==> ERROR: FTPAGENT is not configured. Check the /etc/makepkg.conf file."
+ msg "==> Aborting..."
+ exit 1
+ fi
+ ftpclient=`echo $FTPAGENT | awk {'print $1'}`
+ if [ ! -x $ftpclient ]; then
+ msg "==> ERROR: ftpclient `basename $ftpclient` is not installed."
+ msg "==> Aborting..."
+ exit 1
+ fi
+ proto=`echo $netfile | sed 's|://.*||'`
+ if [ "$proto" != "ftp" -a "$proto" != "http" ]; then
+ msg "==> ERROR: $netfile was not found in the build directory and is not a proper URL."
+ msg "==> Aborting..."
+ exit 1
+ fi
+ msg "==> Downloading $file"
+ $FTPAGENT $netfile 2>&1
+ if [ ! -f $file ]; then
+ msg "==> ERROR: Failed to download $file"
+ msg "==> Aborting..."
+ exit 1
+ fi
+ mkdir -p /var/cache/pacman/src && cp $file /var/cache/pacman/src
+ fi
+ unset cmd
+ case $file in
+ *.tar.gz|*.tar.Z|*.tgz)
+ cmd="tar --use-compress-program=gzip -xf $file" ;;
+ *.tar.bz2)
+ cmd="tar --use-compress-program=bzip2 -xf $file" ;;
+ *.tar)
+ cmd="tar -xf $file" ;;
+ *.zip)
+ cmd="unzip -qq $file" ;;
+ *.gz)
+ cmd="gunzip $file" ;;
+ esac
+ if [ "$cmd" != "" ]; then
+ msg "==> $cmd"
+ $cmd
+ if [ $? -ne 0 ]; then
+ msg "==> ERROR: Failed to extract $file"
+ msg "==> Aborting..."
+ exit 1
+ fi
+ fi
done
# check for existing pkg directory
if [ -d $startdir/pkg ]; then
- msg "==> Removing existing pkg directory..."
- rm -rf $startdir/pkg
+ msg "==> Removing existing pkg directory..."
+ rm -rf $startdir/pkg
fi
mkdir -p $startdir/pkg
@@ -293,8 +289,8 @@ mkdir -p $startdir/pkg
msg "==> Building Package..."
build 2>&1
if [ $? -gt 0 ]; then
- msg "==> Build Failed. Aborting..."
- exit 2
+ msg "==> Build Failed. Aborting..."
+ exit 2
fi
# remove info/doc files
@@ -304,30 +300,36 @@ rm -rf pkg/usr/doc pkg/usr/share/doc
# move /usr/share/man files to /usr/man
if [ -d pkg/usr/share/man ]; then
- mkdir -p pkg/usr/man
- cp -a pkg/usr/share/man/* pkg/usr/man/
- rm -rf pkg/usr/share/man
+ mkdir -p pkg/usr/man
+ cp -a pkg/usr/share/man/* pkg/usr/man/
+ rm -rf pkg/usr/share/man
+fi
+
+# remove /usr/share directory if empty
+if [ -d pkg/usr/share ]; then
+ if [ -z "`ls -1 pkg/usr/share`" ]; then
+ rm -r pkg/usr/share
+ fi
fi
# compress man pages
if [ -d pkg/usr/man ]; then
- msg "==> Compressing man pages..."
- for i in `find pkg/usr/man -type f`; do
- ext=`echo $i | sed 's|.*\.||g'`
- fn=`echo $i | sed 's|.*/||g'`
- if [ "$ext" != "gz" ]; then
- # update symlinks to this manpage
- for ln in `find pkg/usr/man -lname "$fn"`; do
- rm -f $ln
- ln -sf ${fn}.gz ${ln}.gz
- done
- # compress the original
- gzip -9 $i
- fi
- done
+ msg "==> Compressing man pages..."
+ for i in `find pkg/usr/man -type f`; do
+ ext=`echo $i | sed 's|.*\.||g'`
+ fn=`echo $i | sed 's|.*/||g'`
+ if [ "$ext" != "gz" ]; then
+ # update symlinks to this manpage
+ for ln in `find pkg/usr/man -lname "$fn"`; do
+ rm -f $ln
+ ln -sf ${fn}.gz ${ln}.gz
+ done
+ # compress the original
+ gzip -9 $i
+ fi
+ done
fi
-
# strip binaries
cd $startdir
msg "==> Stripping debugging symbols from libraries..."
@@ -338,9 +340,9 @@ find pkg/{,usr,usr/local,opt/*}/{bin,sbin} -type f -exec /usr/bin/strip '{}' ';'
# get some package meta info
builddate=`date -u "+%a %b %d %k:%M:%S %Y"`
if [ "$PACKAGER" != "" ]; then
- packager="$PACKAGER"
+ packager="$PACKAGER"
else
- packager="Arch Linux (http://www.archlinux.org)"
+ packager="Arch Linux (http://www.archlinux.org)"
fi
size=`du -cb $startdir/pkg | tail -1 | awk '{print $1}'`
@@ -353,47 +355,53 @@ date >>.PKGINFO
echo "pkgname = $pkgname" >>.PKGINFO
echo "pkgver = $pkgver-$pkgrel" >>.PKGINFO
echo "pkgdesc = $pkgdesc" >>.PKGINFO
+echo "url = $url" >>.PKGINFO
echo "builddate = $builddate" >>.PKGINFO
echo "packager = $packager" >>.PKGINFO
echo "size = $size" >>.PKGINFO
for depend in "${depends[@]}"; do
- echo "depend = $depend" >>.PKGINFO
+ echo "depend = $depend" >>.PKGINFO
done
for conflict in "${conflicts[@]}"; do
- echo "conflict = $conflict" >>.PKGINFO
+ echo "conflict = $conflict" >>.PKGINFO
done
for bakfile in "${backup[@]}"; do
- echo "backup = $bakfile" >>.PKGINFO
+ echo "backup = $bakfile" >>.PKGINFO
done
# check for an install script
if [ "$install" != "" ]; then
- msg "==> Copying install script..."
- cp $startdir/$install $startdir/pkg/._install
+ msg "==> Copying install script..."
+ cp $startdir/$install $startdir/pkg/.INSTALL
fi
+# build a filelist
+msg "==> Building filelist..."
+cd $startdir/pkg
+tar cv * >/dev/null 2>.FILELIST
+
# tar it up
msg "==> Compressing package..."
cd $startdir/pkg
-if [ -f $startdir/pkg/._install ]; then
- tar czvf $PKGDEST/$pkgname-$pkgver-$pkgrel.pkg.tar.gz .PKGINFO ._install * >../filelist
+if [ -f $startdir/pkg/.INSTALL ]; then
+ cmd="tar czvf $PKGDEST/$pkgname-$pkgver-$pkgrel.pkg.tar.gz .PKGINFO .FILELIST .INSTALL *"
else
- tar czvf $PKGDEST/$pkgname-$pkgver-$pkgrel.pkg.tar.gz .PKGINFO * >../filelist
+ cmd="tar czvf $PKGDEST/$pkgname-$pkgver-$pkgrel.pkg.tar.gz .PKGINFO .FILELIST *"
fi
+$cmd >../filelist
cd $startdir
if [ "$CLEANUP" = "1" ]; then
- msg "==> Cleaning up"
- rm -rf src pkg filelist
+ msg "==> Cleaning up"
+ rm -rf src pkg filelist
fi
-d=`date`
-msg "==> Finished making $pkgname ($d)"
+msg "==> Finished making $pkgname (`date`)"
if [ "$INSTALL" = "1" ]; then
- msg "==> Running pacman --upgrade"
- pacman --upgrade $PKGDEST/$pkgname-$pkgver-$pkgrel.pkg.tar.gz
+ msg "==> Running pacman --upgrade"
+ pacman --upgrade $PKGDEST/$pkgname-$pkgver-$pkgrel.pkg.tar.gz
fi
exit 0
diff --git a/scripts/makeworld b/scripts/makeworld
index 85051bda..fdeb23a3 100755
--- a/scripts/makeworld
+++ b/scripts/makeworld
@@ -1,19 +1,19 @@
#!/bin/bash
toplevel=`pwd`
-version="2.4.1"
+version="2.5"
usage() {
echo "makeworld version $version"
echo "usage: $0 [options] <destdir> <category> [category] ..."
echo "options:"
- echo " -c, --clean Clean up work files after build"
- echo " -s, --syncdeps Install missing dependencies with pacman"
echo " -b, --builddeps Build missing dependencies from source"
+ echo " -c, --clean Clean up work files after build"
echo " -d, --nodeps Skip all dependency checks"
- echo " -i, --install Install package after successful build"
echo " -f, --force Overwrite existing packages"
+ echo " -i, --install Install package after successful build"
echo " -h, --help This help"
+ echo " -s, --syncdeps Install missing dependencies with pacman"
echo
echo " where <category> is one or more directory names under the ABS root"
echo " eg: makeworld -c /packages base lib editors"
diff --git a/src/convertdb.c b/src/convertdb.c
index b3387162..d337dcca 100644
--- a/src/convertdb.c
+++ b/src/convertdb.c
@@ -29,8 +29,7 @@
#include <sys/stat.h>
#include <unistd.h>
#include "list.h"
-
-char* trim(char *str);
+#include "util.h"
int main(int argc, char* argv[])
{
@@ -139,25 +138,4 @@ int main(int argc, char* argv[])
return(0);
}
-/* Trim whitespace and newlines from a string
- */
-char* trim(char *str)
-{
- char *pch = str;
- while(isspace(*pch)) {
- pch++;
- }
- if(pch != str) {
- memmove(str, pch, (strlen(pch) + 1));
- }
-
- pch = (char*)(str + (strlen(str) - 1));
- while(isspace(*pch)) {
- pch--;
- }
- *++pch = '\0';
-
- return str;
-}
-
/* vim: set ts=2 sw=2 noet: */
diff --git a/src/db.c b/src/db.c
index b2489bb1..bf7be9f9 100644
--- a/src/db.c
+++ b/src/db.c
@@ -24,21 +24,10 @@
#include <stdlib.h>
#include <errno.h>
#include <string.h>
-#include <limits.h>
#include <sys/stat.h>
-#include <sys/types.h>
-#include "list.h"
#include "package.h"
-#include "db.h"
#include "util.h"
-#include "pacsync.h"
-#include "pacman.h"
-
-extern PMList *pm_packages;
-extern char *pmo_root;
-extern unsigned short pmo_upgrade;
-
-extern int errno;
+#include "db.h"
/* Verify database integrity and build a list of
* installed packages
@@ -47,14 +36,14 @@ extern int errno;
* 1 if db is not initialized
* 2 if db is corrupt
*/
-pacdb_t* db_open(char *dbpath, char *treename)
+pacdb_t* db_open(char *root, char *pkgdir, char *treename)
{
pacdb_t *db = NULL;
- char path[PATH_MAX];
MALLOC(db, sizeof(pacdb_t));
- snprintf(path, PATH_MAX-1, "%s/%s", dbpath, treename);
- db->dir = opendir(path);
+ MALLOC(db->path, strlen(root)+strlen(pkgdir)+strlen(treename)+2);
+ sprintf(db->path, "%s%s/%s", root, pkgdir, treename);
+ db->dir = opendir(db->path);
if(db->dir == NULL) {
return(NULL);
}
@@ -65,7 +54,14 @@ pacdb_t* db_open(char *dbpath, char *treename)
void db_close(pacdb_t* db)
{
- closedir(db->dir);
+ if(db) {
+ if(db->dir) {
+ closedir(db->dir);
+ }
+ FREE(db->path);
+ }
+ FREE(db);
+
return;
}
@@ -115,6 +111,8 @@ PMList* db_loadpkgs(pacdb_t *db, PMList *pkgcache)
cache = list_add(cache, arr[i]);
}
+ free(arr);
+
return(cache);
}
@@ -174,19 +172,17 @@ pkginfo_t* db_read(pacdb_t *db, struct dirent *ent, unsigned int inforeq)
struct stat buf;
pkginfo_t *info = NULL;
char path[PATH_MAX];
- char topdir[PATH_MAX];
char line[512];
if(ent == NULL) {
return(NULL);
}
- snprintf(topdir, PATH_MAX, "%s%s/%s", pmo_root, PKGDIR, db->treename);
info = newpkg();
/* we always load DESC */
inforeq |= INFRQ_DESC;
- snprintf(path, PATH_MAX, "%s/%s", topdir, ent->d_name);
+ snprintf(path, PATH_MAX, "%s/%s", db->path, ent->d_name);
if(stat(path, &buf)) {
/* directory doesn't exist or can't be opened */
return(NULL);
@@ -194,7 +190,7 @@ pkginfo_t* db_read(pacdb_t *db, struct dirent *ent, unsigned int inforeq)
/* DESC */
if(inforeq & INFRQ_DESC) {
- snprintf(path, PATH_MAX, "%s/%s/desc", topdir, ent->d_name);
+ snprintf(path, PATH_MAX, "%s/%s/desc", db->path, ent->d_name);
fp = fopen(path, "r");
if(fp == NULL) {
fprintf(stderr, "error: %s: %s\n", path, strerror(errno));
@@ -206,32 +202,37 @@ pkginfo_t* db_read(pacdb_t *db, struct dirent *ent, unsigned int inforeq)
}
trim(line);
if(!strcmp(line, "%NAME%")) {
- if(fgets(info->name, 256, fp) == NULL) {
+ if(fgets(info->name, sizeof(info->name), fp) == NULL) {
return(NULL);
}
trim(info->name);
} else if(!strcmp(line, "%VERSION%")) {
- if(fgets(info->version, 64, fp) == NULL) {
+ if(fgets(info->version, sizeof(info->version), fp) == NULL) {
return(NULL);
}
trim(info->version);
} else if(!strcmp(line, "%DESC%")) {
- if(fgets(info->desc, 512, fp) == NULL) {
+ if(fgets(info->desc, sizeof(info->desc), fp) == NULL) {
return(NULL);
}
trim(info->desc);
+ } else if(!strcmp(line, "%URL%")) {
+ if(fgets(info->url, sizeof(info->url), fp) == NULL) {
+ return(NULL);
+ }
+ trim(info->url);
} else if(!strcmp(line, "%BUILDDATE%")) {
- if(fgets(info->builddate, 32, fp) == NULL) {
+ if(fgets(info->builddate, sizeof(info->builddate), fp) == NULL) {
return(NULL);
}
trim(info->builddate);
} else if(!strcmp(line, "%INSTALLDATE%")) {
- if(fgets(info->installdate, 32, fp) == NULL) {
+ if(fgets(info->installdate, sizeof(info->installdate), fp) == NULL) {
return(NULL);
}
trim(info->installdate);
} else if(!strcmp(line, "%PACKAGER%")) {
- if(fgets(info->packager, 64, fp) == NULL) {
+ if(fgets(info->packager, sizeof(info->packager), fp) == NULL) {
return(NULL);
}
trim(info->packager);
@@ -249,7 +250,7 @@ pkginfo_t* db_read(pacdb_t *db, struct dirent *ent, unsigned int inforeq)
/* FILES */
if(inforeq & INFRQ_FILES) {
- snprintf(path, PATH_MAX, "%s/%s/files", topdir, ent->d_name);
+ snprintf(path, PATH_MAX, "%s/%s/files", db->path, ent->d_name);
fp = fopen(path, "r");
if(fp == NULL) {
fprintf(stderr, "error: %s: %s\n", path, strerror(errno));
@@ -275,7 +276,7 @@ pkginfo_t* db_read(pacdb_t *db, struct dirent *ent, unsigned int inforeq)
/* DEPENDS */
if(inforeq & INFRQ_DEPENDS) {
- snprintf(path, PATH_MAX, "%s/%s/depends", topdir, ent->d_name);
+ snprintf(path, PATH_MAX, "%s/%s/depends", db->path, ent->d_name);
fp = fopen(path, "r");
if(fp == NULL) {
fprintf(stderr, "db_read: error: %s: %s\n", path, strerror(errno));
@@ -307,7 +308,7 @@ pkginfo_t* db_read(pacdb_t *db, struct dirent *ent, unsigned int inforeq)
}
/* INSTALL */
- snprintf(path, PATH_MAX, "%s/%s/install", topdir, ent->d_name);
+ snprintf(path, PATH_MAX, "%s/%s/install", db->path, ent->d_name);
if(!stat(path, &buf)) {
info->scriptlet = 1;
}
@@ -317,8 +318,8 @@ pkginfo_t* db_read(pacdb_t *db, struct dirent *ent, unsigned int inforeq)
int db_write(pacdb_t *db, pkginfo_t *info)
{
- FILE *fp = NULL;
char topdir[PATH_MAX];
+ FILE *fp = NULL;
char path[PATH_MAX];
mode_t oldmask;
PMList *lp = NULL;
@@ -326,11 +327,11 @@ int db_write(pacdb_t *db, pkginfo_t *info)
if(info == NULL) {
return(1);
}
- snprintf(topdir, PATH_MAX, "%s%s/%s/%s-%s", pmo_root, PKGDIR, db->treename,
- info->name, info->version);
+ snprintf(topdir, PATH_MAX, "%s/%s-%s", db->path,
+ info->name, info->version);
oldmask = umask(0000);
- mkdir(topdir, 0755);
+ mkdir(topdir, 0755);
umask(oldmask);
/* DESC */
@@ -346,6 +347,8 @@ int db_write(pacdb_t *db, pkginfo_t *info)
fprintf(fp, "%s\n\n", info->version);
fputs("%DESC%\n", fp);
fprintf(fp, "%s\n\n", info->desc);
+ fputs("%URL%\n", fp);
+ fprintf(fp, "%s\n\n", info->url);
fputs("%BUILDDATE%\n", fp);
fprintf(fp, "%s\n\n", info->builddate);
fputs("%INSTALLDATE%\n", fp);
@@ -406,7 +409,7 @@ int db_write(pacdb_t *db, pkginfo_t *info)
}
-PMList* db_find_conflicts(pacdb_t *db, PMList *targets)
+PMList* db_find_conflicts(pacdb_t *db, PMList *targets, char *root)
{
PMList *i, *j, *k;
char *filestr = NULL;
@@ -450,7 +453,7 @@ PMList* db_find_conflicts(pacdb_t *db, PMList *targets)
}*/
/* CHECK 2: check every target against every target */
- vprint("Checking targets against targets...\n");
+ /* orelien - vprint("Checking targets against targets...\n"); */
for(i = targets; i; i = i->next) {
pkginfo_t *p1 = (pkginfo_t*)i->data;
for(j = i; j; j = j->next) {
@@ -458,7 +461,7 @@ PMList* db_find_conflicts(pacdb_t *db, PMList *targets)
if(strcmp(p1->name, p2->name)) {
for(k = p1->files; k; k = k->next) {
filestr = k->data;
- if(!strcmp(filestr, "._install")) {
+ if(!strcmp(filestr, "._install") || !strcmp(filestr, ".INSTALL")) {
continue;
}
if(rindex(filestr, '/') == filestr+strlen(filestr)-1) {
@@ -477,13 +480,13 @@ PMList* db_find_conflicts(pacdb_t *db, PMList *targets)
}
/* CHECK 3: check every target against the filesystem */
- vprint("Checking targets against filesystem...\n");
+ /* orelien - vprint("Checking targets against filesystem...\n"); */
for(i = targets; i; i = i->next) {
pkginfo_t *p = (pkginfo_t*)i->data;
pkginfo_t *dbpkg = NULL;
for(j = p->files; j; j = j->next) {
filestr = (char*)j->data;
- snprintf(path, PATH_MAX, "%s%s", pmo_root, filestr);
+ snprintf(path, PATH_MAX, "%s%s", root, filestr);
if(!stat(path, &buf) && !S_ISDIR(buf.st_mode)) {
int ok = 0;
if(dbpkg == NULL) {
diff --git a/src/db.h b/src/db.h
index 7428e270..11404134 100644
--- a/src/db.h
+++ b/src/db.h
@@ -30,17 +30,18 @@
#define INFRQ_ALL 0xFF
typedef struct __pacdb_t {
+ char *path;
char treename[128];
DIR* dir;
} pacdb_t;
-pacdb_t* db_open(char *dbpath, char *treename);
+pacdb_t* db_open(char *root, char *dbpath, char *treename);
void db_close(pacdb_t *db);
PMList* db_loadpkgs(pacdb_t *db, PMList *pkgcache);
pkginfo_t* db_scan(pacdb_t *db, char *target, unsigned int inforeq);
pkginfo_t* db_read(pacdb_t *db, struct dirent *ent, unsigned int inforeq);
int db_write(pacdb_t *db, pkginfo_t *info);
-PMList* db_find_conflicts(pacdb_t *db, PMList* targets);
+PMList* db_find_conflicts(pacdb_t *db, PMList* targets, char *root);
#endif
/* vim: set ts=2 sw=2 noet: */
diff --git a/src/list.c b/src/list.c
index 717aab2b..dfb8f630 100644
--- a/src/list.c
+++ b/src/list.c
@@ -20,14 +20,9 @@
*/
#include "config.h"
-#include <stdio.h>
#include <stdlib.h>
-#include <limits.h>
-#include <errno.h>
#include <string.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
+#include <stdio.h>
#include "list.h"
PMList* list_new()
@@ -105,6 +100,20 @@ int list_isin(PMList *haystack, void *needle)
return(0);
}
+/* Test for existence of a string in a PMList
+ */
+int is_in(char *needle, PMList *haystack)
+{
+ PMList *lp;
+
+ for(lp = haystack; lp; lp = lp->next) {
+ if(lp->data && !strcmp(lp->data, needle)) {
+ return(1);
+ }
+ }
+ return(0);
+}
+
/* List one is extended and returned
* List two is freed (but not its data)
*/
@@ -131,4 +140,77 @@ PMList* list_last(PMList *list)
return(ptr);
}
+/* Helper function for sorting a list of strings
+ */
+int list_strcmp(const void *s1, const void *s2)
+{
+ char **str1 = (char **)s1;
+ char **str2 = (char **)s2;
+
+ return(strcmp(*str1, *str2));
+}
+
+PMList *list_sort(PMList *list)
+{
+ char **arr = NULL;
+ PMList *lp;
+ unsigned int arrct;
+ int i;
+
+ if(list == NULL) {
+ return(NULL);
+ }
+
+ arrct = list_count(list);
+ arr = (char **)malloc(arrct*sizeof(char*));
+ for(lp = list, i = 0; lp; lp = lp->next) {
+ arr[i++] = (char *)lp->data;
+ }
+
+ qsort(arr, (size_t)arrct, sizeof(char *), list_strcmp);
+
+ lp = NULL;
+ for(i = 0; i < arrct; i++) {
+ lp = list_add(lp, strdup(arr[i]));
+ }
+
+ free(arr);
+
+ return(lp);
+}
+
+void list_display(const char *title, PMList *list)
+{
+ PMList *lp;
+ int cols, len, maxcols = 80;
+ char *cenv = NULL;
+
+ cenv = getenv("COLUMNS");
+ if(cenv) {
+ maxcols = atoi(cenv);
+ }
+
+ len = strlen(title);
+ printf("%s", title);
+
+ if(list) {
+ for(lp = list, cols = len; lp; lp = lp->next) {
+ int s = strlen((char*)lp->data)+1;
+ if(s+cols >= maxcols) {
+ int i;
+ cols = len;
+ printf("\n");
+ for (i = 0; i < len; i++) {
+ printf(" ");
+ }
+ }
+ printf("%s ", (char*)lp->data);
+ cols += s;
+ }
+ printf("\n");
+ } else {
+ printf("None\n");
+ }
+}
+
/* vim: set ts=2 sw=2 noet: */
diff --git a/src/list.h b/src/list.h
index 68ff5651..edfc6f97 100644
--- a/src/list.h
+++ b/src/list.h
@@ -1,3 +1,23 @@
+/*
+ * pacman
+ *
+ * Copyright (c) 2002 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_LIST_H
#define _PAC_LIST_H
@@ -13,8 +33,12 @@ void list_free(PMList* list);
PMList* list_add(PMList* list, void* data);
int list_count(PMList* list);
int list_isin(PMList *haystack, void *needle);
+int is_in(char *needle, PMList *haystack);
PMList* list_merge(PMList *one, PMList *two);
PMList* list_last(PMList* list);
+int list_strcmp(const void *s1, const void *s2);
+PMList *list_sort(PMList *list);
+void list_display(const char *title, PMList *list);
#endif
diff --git a/src/md5.h b/src/md5.h
index b5ce6fd9..e6e4ea64 100644
--- a/src/md5.h
+++ b/src/md5.h
@@ -45,4 +45,7 @@ void MD5Init(MD5_CTX *);
void MD5Update(MD5_CTX *, unsigned char *, unsigned int);
void MD5Final(unsigned char [16], MD5_CTX *);
+char* MDFile(char *);
+void MDPrint(unsigned char [16]);
+
/* vim: set ts=2 sw=2 noet: */
diff --git a/src/md5driver.c b/src/md5driver.c
index 52c7189a..efd43fe6 100644
--- a/src/md5driver.c
+++ b/src/md5driver.c
@@ -29,9 +29,6 @@ documentation and/or software.
#define TEST_BLOCK_LEN 1000
#define TEST_BLOCK_COUNT 1000
-char* MDFile(char *);
-void MDPrint(unsigned char [16]);
-
#define MD_CTX MD5_CTX
#define MDInit MD5Init
#define MDUpdate MD5Update
diff --git a/src/package.c b/src/package.c
index 6f41fc58..d41e1d85 100644
--- a/src/package.c
+++ b/src/package.c
@@ -24,39 +24,45 @@
#include <stdlib.h>
#include <limits.h>
#include <fcntl.h>
-#include <unistd.h>
#include <string.h>
-#include "list.h"
-#include "package.h"
-#include "db.h"
+#include <libtar.h>
+#include <zlib.h>
#include "util.h"
-#include "pacsync.h"
-#include "pacman.h"
-
-extern tartype_t gztype;
+#include "package.h"
pkginfo_t* load_pkg(char *pkgfile, unsigned short output)
{
char *expath;
- char *descfile;
int i;
+ int config = 0;
+ int filelist = 0;
TAR *tar;
pkginfo_t *info = NULL;
PMList *backup = NULL;
PMList *lp;
+ tartype_t gztype = {
+ (openfunc_t) gzopen_frontend,
+ (closefunc_t)gzclose,
+ (readfunc_t) gzread,
+ (writefunc_t)gzwrite
+ };
info = newpkg();
- descfile = strdup("/tmp/pacman_XXXXXX");
if(tar_open(&tar, pkgfile, &gztype, O_RDONLY, 0, TAR_GNU) == -1) {
perror("could not open package");
return(NULL);
}
- vprint("load_pkg: loading filelist from package...\n");
for(i = 0; !th_read(tar); i++) {
+ if(config && filelist) {
+ /* we have everything we need */
+ break;
+ }
if(!strcmp(th_get_pathname(tar), ".PKGINFO")) {
+ char *descfile;
+
/* extract this file into /tmp. it has info for us */
- vprint("load_pkg: found package description file.\n");
+ descfile = strdup("/tmp/pacman_XXXXXX");
mkstemp(descfile);
tar_extract_file(tar, descfile);
/* parse the info file */
@@ -74,14 +80,43 @@ pkginfo_t* load_pkg(char *pkgfile, unsigned short output)
info->backup = list_add(info->backup, lp->data);
}
}
+ config = 1;
+ FREE(descfile);
continue;
- }
- if(!strcmp(th_get_pathname(tar), "._install")) {
+ } else if(!strcmp(th_get_pathname(tar), "._install") || !strcmp(th_get_pathname(tar), ".INSTALL")) {
info->scriptlet = 1;
+ } else if(!strcmp(th_get_pathname(tar), ".FILELIST")) {
+ /* Build info->files from the filelist */
+ FILE *fp;
+ char *fn;
+ char *str;
+
+ MALLOC(str, PATH_MAX);
+ fn = strdup("/tmp/pacman_XXXXXX");
+ mkstemp(fn);
+ tar_extract_file(tar, fn);
+ fp = fopen(fn, "r");
+ while(!feof(fp)) {
+ if(fgets(str, PATH_MAX, fp) == NULL) {
+ continue;
+ }
+ trim(str);
+ info->files = list_add(info->files, strdup(str));
+ }
+ FREE(str);
+ fclose(fp);
+ if(unlink(fn)) {
+ fprintf(stderr, "warning: could not remove tempfile %s\n", fn);
+ }
+ FREE(fn);
+ filelist = 1;
} else {
- expath = strdup(th_get_pathname(tar));
- /* add the path to the list */
- info->files = list_add(info->files, expath);
+ if(!filelist) {
+ /* no .FILELIST present in this package.. build the filelist the */
+ /* old-fashioned way, one at a time */
+ expath = strdup(th_get_pathname(tar));
+ info->files = list_add(info->files, expath);
+ }
}
if(TH_ISREG(tar) && tar_skip_regfile(tar)) {
@@ -93,9 +128,8 @@ pkginfo_t* load_pkg(char *pkgfile, unsigned short output)
expath = NULL;
}
tar_close(tar);
- FREE(descfile);
- if(!strlen(info->name) || !strlen(info->version)) {
+ if(!config) {
fprintf(stderr, "load_pkg: missing package info file in %s\n", pkgfile);
return(NULL);
}
@@ -147,6 +181,8 @@ int parse_descfile(char *descfile, pkginfo_t *info, PMList **backup, int output)
strncpy(info->version, ptr, sizeof(info->version));
} else if(!strcmp(key, "PKGDESC")) {
strncpy(info->desc, ptr, sizeof(info->desc));
+ } else if(!strcmp(key, "URL")) {
+ strncpy(info->url, ptr, sizeof(info->url));
} else if(!strcmp(key, "BUILDDATE")) {
strncpy(info->builddate, ptr, sizeof(info->builddate));
} else if(!strcmp(key, "INSTALLDATE")) {
@@ -188,6 +224,7 @@ pkginfo_t* newpkg()
pkg->name[0] = '\0';
pkg->version[0] = '\0';
pkg->desc[0] = '\0';
+ pkg->url[0] = '\0';
pkg->builddate[0] = '\0';
pkg->installdate[0] = '\0';
pkg->packager[0] = '\0';
@@ -227,4 +264,58 @@ int pkgcmp(const void *p1, const void *p2)
return(strcmp(pkg1[0]->name, pkg2[0]->name));
}
+/* Test for existence of a package in a PMList*
+ * of pkginfo_t*
+ *
+ * returns: 0 for no match
+ * 1 for identical match
+ * -1 for name-only match (version mismatch)
+ */
+int is_pkgin(pkginfo_t *needle, PMList *haystack)
+{
+ PMList *lp;
+ pkginfo_t *info;
+
+ for(lp = haystack; lp; lp = lp->next) {
+ info = (pkginfo_t*)lp->data;
+ if(info && !strcmp(info->name, needle->name)) {
+ if(!strcmp(info->version, needle->version)) {
+ return(1);
+ }
+ return(-1);
+ }
+ }
+ return(0);
+}
+
+/* Display the content of a package
+ */
+void dump_pkg(pkginfo_t *info)
+{
+ PMList *pm;
+
+ if(info == NULL) {
+ return;
+ }
+
+ printf("Name : %s\n", info->name);
+ printf("Version : %s\n", info->version);
+ printf("Packager : %s\n", info->packager);
+ printf("URL: : %s\n", info->url);
+ printf("Size : %ld\n", info->size);
+ printf("Build Date : %s %s\n", info->builddate, strlen(info->builddate) ? "UTC" : "");
+ printf("Install Date : %s %s\n", info->installdate, strlen(info->installdate) ? "UTC" : "");
+ printf("Install Script: %s\n", (info->scriptlet ? "yes" : "no"));
+ pm = list_sort(info->depends);
+ list_display("Depends On : ", pm);
+ FREE(pm);
+ pm = list_sort(info->requiredby);
+ list_display("Required By : ", pm);
+ FREE(pm);
+ pm = list_sort(info->conflicts);
+ list_display("Conflicts With: ", pm);
+ FREE(pm);
+ printf("Description : %s\n", info->desc);
+}
+
/* vim: set ts=2 sw=2 noet: */
diff --git a/src/package.h b/src/package.h
index f9dc9477..72b015c3 100644
--- a/src/package.h
+++ b/src/package.h
@@ -21,6 +21,8 @@
#ifndef _PAC_PACKAGE_H
#define _PAC_PACKAGE_H
+#include "list.h"
+
/* mods for depend_t.mod */
#define DEP_ANY 0
#define DEP_EQ 1
@@ -33,6 +35,7 @@ typedef struct __pkginfo_t {
char name[256];
char version[64];
char desc[512];
+ char url[255];
char builddate[32];
char installdate[32];
char packager[64];
@@ -62,6 +65,8 @@ int parse_descfile(char *descfile, pkginfo_t *info, PMList **backup, int output)
pkginfo_t* newpkg();
void freepkg(pkginfo_t *pkg);
int pkgcmp(const void *p1, const void *p2);
+int is_pkgin(pkginfo_t *needle, PMList *haystack);
+void dump_pkg(pkginfo_t *info);
#endif
/* vim: set ts=2 sw=2 noet: */
diff --git a/src/pacman.c b/src/pacman.c
index efbf2c17..79f2f996 100644
--- a/src/pacman.c
+++ b/src/pacman.c
@@ -24,30 +24,26 @@
#include <stdarg.h>
#include <stdlib.h>
#include <signal.h>
-#include <limits.h>
#include <errno.h>
#include <fcntl.h>
#include <string.h>
-#include <dirent.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <time.h>
+#include <getopt.h>
+#include <zlib.h>
+#include <libtar.h>
/* pacman */
-#include "list.h"
+#include "rpmvercmp.h"
#include "md5.h"
+#include "list.h"
#include "package.h"
-#include "db.h"
#include "util.h"
+#include "db.h"
#include "pacsync.h"
#include "pacman.h"
-extern tartype_t gztype;
-
-/* other prototypes */
-int rpmvercmp(const char *a, const char *b);
-char* MDFile(char *);
-
/*
* GLOBALS
*
@@ -77,6 +73,7 @@ unsigned short pmo_s_sync = 0;
unsigned short pmo_s_search = 0;
unsigned short pmo_s_clean = 0;
/* configuration file options */
+char *pmo_dbpath = NULL;
PMList *pmo_noupgrade = NULL;
PMList *pmo_ignorepkg = NULL;
unsigned short pmo_nopassiveftp = 0;
@@ -91,57 +88,57 @@ PMList *pm_targets = NULL;
char *lckfile = "/tmp/pacman.lck";
char *workfile = NULL;
+enum {READ_ONLY, READ_WRITE} pm_access;
int main(int argc, char *argv[])
{
int ret = 0;
char *ptr = NULL;
- char *dbpath = NULL;
char path[PATH_MAX];
pacdb_t *db_local = NULL;
- PMList *lp;
/* default root */
MALLOC(pmo_root, PATH_MAX);
strcpy(pmo_root, "/");
+ /* default dbpath */
+ MALLOC(pmo_dbpath, PATH_MAX);
+ strcpy(pmo_dbpath, PKGDIR);
if(argc < 2) {
usage(PM_MAIN, (char*)basename(argv[0]));
return(0);
}
+ /* parse the command line */
ret = parseargs(PM_ADD, argc, argv);
if(ret) {
return(ret);
}
/* check for permission */
+ pm_access = READ_ONLY;
if(pmo_op != PM_MAIN && pmo_op != PM_QUERY && pmo_op != PM_DEPTEST) {
if(pmo_op == PM_SYNC && pmo_s_search) {
/* special case: PM_SYNC can be used w/ pmo_s_search by any user */
} else {
- uid_t uid = geteuid();
- if(uid != 0) {
+ if(geteuid() != 0) {
fprintf(stderr, "error: you cannot perform this operation unless you are root.\n");
return(1);
}
+ pm_access = READ_WRITE;
+ /* lock */
+ if(lckmk(lckfile, 1, 1) == -1) {
+ fprintf(stderr, "error: unable to lock pacman database.\n");
+ fprintf(stderr, " if you're sure pacman is not already running, you\n");
+ fprintf(stderr, " can remove %s\n", lckfile);
+ return(32);
+ }
}
}
vprint("Installation Root: %s\n", pmo_root);
- if(pm_targets) {
- vprint("Targets:\n");
- for(lp = pm_targets; lp; lp = lp->next) {
- vprint(" %s\n", lp->data);
- }
- }
-
- /* lock */
- if(lckmk(lckfile, 1, 1) == -1) {
- fprintf(stderr, "error: unable to lock pacman database.\n");
- fprintf(stderr, " if you're sure pacman is not already running, you\n");
- fprintf(stderr, " can remove %s\n", lckfile);
- return(32);
+ if(pmo_verbose) {
+ list_display("Targets: ", pm_targets);
}
/* set signal handlers */
@@ -164,28 +161,27 @@ int main(int argc, char *argv[])
pmo_root = ptr;
}
/* db location */
- MALLOC(dbpath, PATH_MAX);
- snprintf(dbpath, PATH_MAX-1, "%s%s", pmo_root, PKGDIR);
- vprint("Top-level DB Path: %s\n", dbpath);
+ vprint("Top-level DB Path: %s%s\n", pmo_root, pmo_dbpath);
- db_local = db_open(dbpath, "local");
+ db_local = db_open(pmo_root, pmo_dbpath, "local");
if(db_local == NULL) {
/* couldn't open the db directory - try creating it */
char path[PATH_MAX];
- snprintf(path, PATH_MAX, "%s/local", dbpath);
- vprint("initializing database...\n", path);
- ret = makepath(path);
+ snprintf(path, PATH_MAX, "%s%s/local", pmo_root, pmo_dbpath);
+ vprint("initializing database %s...\n", path);
+ ret = makepath(path);
if(ret) {
fprintf(stderr, "error: could not create database.\n");
cleanup(1);
}
- if((db_local = db_open(dbpath, "local")) == NULL) {
+ if((db_local = db_open(pmo_root, pmo_dbpath, "local")) == NULL) {
fprintf(stderr, "error: could not open database.\n");
cleanup(1);
}
}
+
/* load pm_packages cache */
pm_packages = db_loadpkgs(db_local, pm_packages);
@@ -203,7 +199,7 @@ int main(int argc, char *argv[])
}
db_close(db_local);
FREE(pmo_root);
- FREE(dbpath);
+ FREE(pmo_dbpath);
cleanup(ret);
/* not reached */
return(0);
@@ -284,7 +280,6 @@ int pacman_deptest(pacdb_t *db, PMList *targets)
int pacman_sync(pacdb_t *db, PMList *targets)
{
- char dbpath[PATH_MAX];
int allgood = 1, confirm = 0;
int cols;
PMList *i, *j, *k;
@@ -329,8 +324,7 @@ int pacman_sync(pacdb_t *db, PMList *targets)
dbsync_t *dbs = NULL;
sync_t *sync = (sync_t*)i->data;
- snprintf(dbpath, PATH_MAX, "%s%s", pmo_root, PKGDIR);
- db_sync = db_open(dbpath, sync->treename);
+ db_sync = db_open(pmo_root, PKGDIR, sync->treename);
if(db_sync == NULL) {
fprintf(stderr, "error: could not open sync database: %s\n", sync->treename);
fprintf(stderr, " have you used --refresh yet?\n");
@@ -403,6 +397,7 @@ int pacman_sync(pacdb_t *db, PMList *targets)
}
if(!found) {
/*fprintf(stderr, "%s: not found in sync db. skipping.", local->name);*/
+ FREE(sync);
continue;
}
/* compare versions and see if we need to upgrade */
@@ -412,40 +407,32 @@ int pacman_sync(pacdb_t *db, PMList *targets)
fprintf(stderr, ":: %s-%s: local version is newer\n",
local->name, local->version);
newer = 1;
+ FREE(sync);
continue;
} else if(cmp == 0) {
/* versions are identical */
+ FREE(sync);
continue;
} else if(is_in((char*)i->data, pmo_ignorepkg)) {
/* package should be ignored (IgnorePkg) */
fprintf(stderr, ":: %s-%s: ignoring package upgrade (%s)\n",
local->name, local->version, sync->pkg->version);
ignore = 1;
+ FREE(sync);
continue;
- } else {
- PMList *lp = NULL;
- int found = 0;
- /* re-fetch the package record with dependency info */
- sync->pkg = db_scan(sync->dbs->db, sync->pkg->name, INFRQ_DESC | INFRQ_DEPENDS);
- /* add to the targets list */
- for(found = 0, lp = final; lp && !found; lp = lp->next) {
- syncpkg_t *s = (syncpkg_t*)lp->data;
- if(s && !strcmp(s->pkg->name, sync->pkg->name)) {
- found = 1;
- }
- }
+ }
+
+ /* re-fetch the package record with dependency info */
+ sync->pkg = db_scan(sync->dbs->db, sync->pkg->name, INFRQ_DESC | INFRQ_DEPENDS);
+
+ /* add to the targets list */
+ found = is_pkginsync(sync, final);
+ if(!found) {
+ allgood = !resolvedeps(db, databases, sync, final, trail);
+ /* check again, as resolvedeps could have added our target for us */
+ found = is_pkginsync(sync, final);
if(!found) {
- allgood = !resolvedeps(db, databases, sync, final, trail);
- /* check again, as resolvedeps could have added our target for us */
- for(found = 0, lp = final; lp && !found; lp = lp->next) {
- syncpkg_t *s = (syncpkg_t*)lp->data;
- if(s && !strcmp(s->pkg->name, sync->pkg->name)) {
- found = 1;
- }
- }
- if(!found) {
- final = list_add(final, sync);
- }
+ final = list_add(final, sync);
}
}
}
@@ -480,6 +467,8 @@ int pacman_sync(pacdb_t *db, PMList *targets)
if(!found) {
fprintf(stderr, "%s: not found in sync db\n", (char*)i->data);
allgood = 0;
+ freepkg(local);
+ FREE(sync);
continue;
}
if(local && !pmo_s_downloadonly) {
@@ -488,36 +477,31 @@ int pacman_sync(pacdb_t *db, PMList *targets)
if(cmp > 0) {
/* local version is newer - get confirmation first */
if(!yesno(":: %s-%s: local version is newer. Upgrade anyway? [Y/n] ", local->name, local->version)) {
+ freepkg(local);
+ freepkg(sync->pkg);
+ FREE(sync);
continue;
}
} else if(cmp == 0) {
/* versions are identical */
if(!yesno(":: %s-%s: is up to date. Upgrade anyway? [Y/n] ", local->name, local->version)) {
+ freepkg(local);
+ freepkg(sync->pkg);
+ FREE(sync);
continue;
}
}
}
- /* add to targets list */
- found = 0;
- for(j = final; j; j = j->next) {
- syncpkg_t *tmp = (syncpkg_t*)j->data;
- if(tmp && !strcmp(tmp->pkg->name, sync->pkg->name)) {
- found = 1;
- }
- }
- if(!found) {
+ freepkg(local);
+
+ found = is_pkginsync(sync, final);
+ if(!found && !pmo_nodeps) {
allgood = !resolvedeps(db, databases, sync, final, trail);
/* check again, as resolvedeps could have added our target for us */
- found = 0;
- for(j = final; j; j = j->next) {
- syncpkg_t *tmp = (syncpkg_t*)j->data;
- if(tmp && !strcmp(tmp->pkg->name, sync->pkg->name)) {
- found = 1;
- }
- }
- if(!found) {
- final = list_add(final, sync);
- }
+ found = is_pkginsync(sync, final);
+ }
+ if(!found) {
+ final = list_add(final, sync);
}
}
}
@@ -535,33 +519,36 @@ int pacman_sync(pacdb_t *db, PMList *targets)
}
}
- deps = checkdeps(db, PM_UPGRADE, list);
- if(deps) {
- fprintf(stderr, "error: unresolvable conflicts/dependencies:\n");
- for(i = deps; i; i = i->next) {
- depmissing_t *miss = (depmissing_t*)i->data;
- if(miss->type == CONFLICT) {
- fprintf(stderr, " %s: conflicts with %s\n", miss->target, miss->depend.name);
- } else if(miss->type == DEPEND || miss->type == REQUIRED) {
- fprintf(stderr, " %s: requires %s", miss->target, miss->depend.name);
- switch(miss->depend.mod) {
- case DEP_EQ: fprintf(stderr, "=%s", miss->depend.version); break;
- case DEP_GE: fprintf(stderr, ">=%s", miss->depend.version); break;
- case DEP_LE: fprintf(stderr, "<=%s", miss->depend.version); break;
- }
- if(miss->type == DEPEND) {
- fprintf(stderr, " but it is not in the sync db\n");
- } else {
- fprintf(stderr, "\n");
+ if(!pmo_nodeps && !pmo_s_upgrade) {
+ deps = checkdeps(db, PM_UPGRADE, list);
+ if(deps) {
+ fprintf(stderr, "error: unresolvable conflicts/dependencies:\n");
+ for(i = deps; i; i = i->next) {
+ depmissing_t *miss = (depmissing_t*)i->data;
+ if(miss->type == CONFLICT) {
+ fprintf(stderr, " %s: conflicts with %s\n", miss->target, miss->depend.name);
+ } else if(miss->type == DEPEND || miss->type == REQUIRED) {
+ fprintf(stderr, " %s: requires %s", miss->target, miss->depend.name);
+ switch(miss->depend.mod) {
+ case DEP_EQ: fprintf(stderr, "=%s", miss->depend.version); break;
+ case DEP_GE: fprintf(stderr, ">=%s", miss->depend.version); break;
+ case DEP_LE: fprintf(stderr, "<=%s", miss->depend.version); break;
+ }
+ if(miss->type == DEPEND) {
+ fprintf(stderr, " but it is not in the sync db\n");
+ } else {
+ fprintf(stderr, "\n");
+ }
}
+ FREE(miss);
+ i->data = NULL;
}
- FREE(miss);
- i->data = NULL;
+ list_free(deps);
+ /* abort mission */
+ allgood = 0;
}
- list_free(deps);
- /* abort mission */
- allgood = 0;
}
+
/* cleanup */
for(i = list; i; i = i->next) {
i->data = NULL;
@@ -641,6 +628,7 @@ int pacman_sync(pacdb_t *db, PMList *targets)
snprintf(path, PATH_MAX, "%s-%s.pkg.tar.gz", sync->pkg->name, sync->pkg->version);
files = list_add(files, strdup(path));
} else {
+ vprint(" %s-%s.pkg.tar.gz is already in the cache\n", sync->pkg->name, sync->pkg->version);
count++;
}
}
@@ -719,7 +707,7 @@ int pacman_sync(pacdb_t *db, PMList *targets)
for(i = final; i; i = i->next) {
syncpkg_t *sync = (syncpkg_t*)i->data;
if(sync) freepkg(sync->pkg);
- free(sync);
+ FREE(sync);
i->data = NULL;
}
for(i = trail; i; i = i->next) {
@@ -730,7 +718,7 @@ int pacman_sync(pacdb_t *db, PMList *targets)
dbsync_t *dbs = (dbsync_t*)i->data;
db_close(dbs->db);
list_free(dbs->pkgcache);
- free(dbs);
+ FREE(dbs);
i->data = NULL;
}
list_free(databases);
@@ -751,6 +739,12 @@ int pacman_add(pacdb_t *db, PMList *targets)
PMList *alltargs = NULL;
PMList *filenames = NULL;
unsigned short real_pmo_upgrade;
+ tartype_t gztype = {
+ (openfunc_t) gzopen_frontend,
+ (closefunc_t)gzclose,
+ (readfunc_t) gzread,
+ (writefunc_t)gzwrite
+ };
if(targets == NULL) {
return(0);
@@ -766,13 +760,14 @@ int pacman_add(pacdb_t *db, PMList *targets)
return(1);
}
if(pmo_freshen) {
- /* only upgrade/install this package if it is already installed */
+ /* only upgrade/install this package if it is already installed and at a lesser version */
pkginfo_t *dummy = db_scan(db, info->name, INFRQ_DESC);
- if(dummy == NULL) {
+ if(dummy == NULL || rpmvercmp(dummy->version, info->version) >= 0) {
freepkg(info);
info = NULL;
continue;
}
+ freepkg(dummy);
}
alltargs = list_add(alltargs, info);
filenames = list_add(filenames, strdup(targ->data));
@@ -810,7 +805,7 @@ int pacman_add(pacdb_t *db, PMList *targets)
if(!pmo_force) {
printf("checking for conflicts... ");
fflush(stdout);
- lp = db_find_conflicts(db, alltargs);
+ lp = db_find_conflicts(db, alltargs, pmo_root);
if(lp) {
printf("\nerror: the following file conflicts were found:\n");
for(j = lp; j; j = j->next) {
@@ -884,12 +879,12 @@ int pacman_add(pacdb_t *db, PMList *targets)
char pathname[PATH_MAX];
strncpy(pathname, th_get_pathname(tar), PATH_MAX);
- if(!strcmp(pathname, ".PKGINFO")) {
+ if(!strcmp(pathname, ".PKGINFO") || !strcmp(pathname, ".FILELIST")) {
tar_skip_regfile(tar);
continue;
}
- if(!strcmp(pathname, "._install")) {
+ if(!strcmp(pathname, "._install") || !strcmp(pathname, ".INSTALL")) {
/* the install script goes inside the db */
snprintf(expath, PATH_MAX, "%s%s/%s/%s-%s/install", pmo_root,
PKGDIR, db->treename, info->name, info->version);
@@ -1279,7 +1274,7 @@ int pacman_remove(pacdb_t *db, PMList *targets)
}
}
} else {
- /*vprint(" unlinking %s\n", line);*/
+ vprint(" unlinking %s\n", line);
if(unlink(line)) {
perror("cannot remove file");
}
@@ -1389,13 +1384,12 @@ int pacman_query(pacdb_t *db, PMList *targets)
printf("\n");
} else if(pmo_q_list) {
for(lp = info->files; lp; lp = lp->next) {
- if(strcmp(lp->data, ".PKGINFO")) {
- printf("%s %s\n", info->name, (char*)lp->data);
- }
+ printf("%s %s\n", info->name, (char*)lp->data);
}
- } else if(!pmo_q_info) {
+ } else {
printf("%s %s\n", info->name, info->version);
}
+ freepkg(info);
continue;
}
@@ -1417,6 +1411,7 @@ int pacman_query(pacdb_t *db, PMList *targets)
gotcha = 1;
}
}
+ freepkg(info);
}
if(!gotcha) {
fprintf(stderr, "No package owns %s\n", package);
@@ -1442,6 +1437,7 @@ int pacman_query(pacdb_t *db, PMList *targets)
for(q = info->files; q; q = q->next) {
printf("%s %s%s\n", info->name, pmo_root, (char*)q->data);
}
+ freepkg(info);
} else {
printf("%s %s\n", tmpp->name, tmpp->version);
}
@@ -1449,70 +1445,12 @@ int pacman_query(pacdb_t *db, PMList *targets)
} else {
/* find a target */
if(pmo_q_info) {
- int cols;
-
info = db_scan(db, package, INFRQ_DESC | INFRQ_DEPENDS);
if(info == NULL) {
fprintf(stderr, "Package \"%s\" was not found.\n", package);
return(2);
}
-
- printf("Name : %s\n", info->name);
- printf("Version : %s\n", info->version);
- printf("Packager : %s\n", info->packager);
- printf("Size : %ld\n", info->size);
- printf("Build Date : %s %s\n", info->builddate, strlen(info->builddate) ? "UTC" : "");
- printf("Install Date : %s %s\n", info->installdate, strlen(info->installdate) ? "UTC" : "");
- printf("Install Script: %s\n", (info->scriptlet ? "yes" : "no"));
- printf("Depends On : ");
- if(info->depends) {
- for(lp = info->depends, cols = 16; lp; lp = lp->next) {
- int s = strlen((char*)lp->data)+1;
- if(s+cols > 79) {
- cols = 16;
- printf("\n%16s%s ", " ", (char*)lp->data);
- } else {
- printf("%s ", (char*)lp->data);
- }
- cols += s;
- }
- printf("\n");
- } else {
- printf("None\n");
- }
- printf("Required By : ");
- if(info->requiredby) {
- for(lp = info->requiredby, cols = 16; lp; lp = lp->next) {
- int s = strlen((char*)lp->data)+1;
- if(s+cols > 79) {
- cols = 16;
- printf("\n%16s%s ", " ", (char*)lp->data);
- } else {
- printf("%s ", (char*)lp->data);
- }
- cols += s;
- }
- printf("\n");
- } else {
- printf("None\n");
- }
- printf("Conflicts With: ");
- if(info->conflicts) {
- for(lp = info->conflicts, cols = 16; lp; lp = lp->next) {
- int s = strlen((char*)lp->data)+1;
- if(s+cols > 79) {
- cols = 16;
- printf("\n%16s%s ", " ", (char*)lp->data);
- } else {
- printf("%s ", (char*)lp->data);
- }
- cols += s;
- }
- printf("\n");
- } else {
- printf("None\n");
- }
- printf("Description : %s\n", info->desc);
+ dump_pkg(info);
printf("\n");
} else if(pmo_q_list) {
info = db_scan(db, package, INFRQ_DESC | INFRQ_FILES);
@@ -1531,19 +1469,16 @@ int pacman_query(pacdb_t *db, PMList *targets)
}
printf("%s %s\n", info->name, info->version);
}
+ freepkg(info);
}
}
- if(info) {
- freepkg(info);
- }
-
return(0);
}
int pacman_upgrade(pacdb_t *db, PMList *targets)
{
- /* this is basically just a remove,add process. pacman_add() will */
+ /* this is basically just a remove-then-add process. pacman_add() will */
/* handle it */
pmo_upgrade = 1;
return(pacman_add(db, targets));
@@ -1907,6 +1842,405 @@ int splitdep(char *depstr, depend_t *depend)
return(0);
}
+/* Look for a filename in a pkginfo_t.backup list. If we find it,
+ * then we return the md5 hash (parsed from the same line)
+ */
+char* needbackup(char* file, PMList *backup)
+{
+ PMList *lp;
+
+ /* run through the backup list and parse out the md5 hash for our file */
+ for(lp = backup; lp; lp = lp->next) {
+ char* str = strdup(lp->data);
+ char* ptr;
+
+ /* tab delimiter */
+ ptr = index(str, '\t');
+ if(ptr == NULL) {
+ FREE(str);
+ continue;
+ }
+ *ptr = '\0';
+ ptr++;
+ /* now str points to the filename and ptr points to the md5 hash */
+ if(!strcmp(file, str)) {
+ char *md5 = strdup(ptr);
+ FREE(str);
+ return(md5);
+ }
+ FREE(str);
+ }
+ return(NULL);
+}
+
+/* Parse command-line arguments for each operation
+ * op: the operation code requested
+ * argc: argc
+ * argv: argv
+ *
+ * Returns: 0 on success, 1 on error
+ */
+int parseargs(int op, int argc, char **argv)
+{
+ int opt;
+ int option_index = 0;
+ static struct option opts[] =
+ {
+ {"add", no_argument, 0, 'A'},
+ {"remove", no_argument, 0, 'R'},
+ {"upgrade", no_argument, 0, 'U'},
+ {"freshen", no_argument, 0, 'F'},
+ {"query", no_argument, 0, 'Q'},
+ {"sync", no_argument, 0, 'S'},
+ {"deptest", no_argument, 0, 'T'},
+ {"vertest", no_argument, 0, 'Y'},
+ {"resolve", no_argument, 0, 'D'},
+ {"root", required_argument, 0, 'r'},
+ {"verbose", no_argument, 0, 'v'},
+ {"version", no_argument, 0, 'V'},
+ {"help", no_argument, 0, 'h'},
+ {"search", no_argument, 0, 's'},
+ {"clean", no_argument, 0, 'c'},
+ {"force", no_argument, 0, 'f'},
+ {"nodeps", no_argument, 0, 'd'},
+ {"nosave", no_argument, 0, 'n'},
+ {"owns", no_argument, 0, 'o'},
+ {"list", no_argument, 0, 'l'},
+ {"file", no_argument, 0, 'p'},
+ {"info", no_argument, 0, 'i'},
+ {"sysupgrade", no_argument, 0, 'u'},
+ {"downloadonly", no_argument, 0, 'w'},
+ {"refresh", no_argument, 0, 'y'},
+ {"cascade", no_argument, 0, 'c'},
+ {0, 0, 0, 0}
+ };
+
+ while((opt = getopt_long(argc, argv, "ARUFQSTDYr:vhscVfnoldpiuwy", opts, &option_index))) {
+ if(opt < 0) {
+ break;
+ }
+ switch(opt) {
+ case 0: break;
+ case 'A': pmo_op = (pmo_op != PM_MAIN ? 0 : PM_ADD); break;
+ case 'R': pmo_op = (pmo_op != PM_MAIN ? 0 : PM_REMOVE); break;
+ case 'U': pmo_op = (pmo_op != PM_MAIN ? 0 : PM_UPGRADE); break;
+ case 'F': pmo_op = (pmo_op != PM_MAIN ? 0 : PM_UPGRADE); pmo_freshen = 1; break;
+ case 'Q': pmo_op = (pmo_op != PM_MAIN ? 0 : PM_QUERY); break;
+ case 'S': pmo_op = (pmo_op != PM_MAIN ? 0 : PM_SYNC); break;
+ case 'T': pmo_op = (pmo_op != PM_MAIN ? 0 : PM_DEPTEST); break;
+ case 'Y': pmo_op = (pmo_op != PM_MAIN ? 0 : PM_DEPTEST); pmo_d_vertest = 1; break;
+ case 'D': pmo_op = (pmo_op != PM_MAIN ? 0 : PM_DEPTEST); pmo_d_resolve = 1; break;
+ case 'h': pmo_help = 1; break;
+ case 'V': pmo_version = 1; break;
+ case 'v': pmo_verbose = 1; break;
+ case 'f': pmo_force = 1; break;
+ case 'd': pmo_nodeps = 1; break;
+ case 'n': pmo_nosave = 1; break;
+ case 'l': pmo_q_list = 1; break;
+ case 'p': pmo_q_isfile = 1; break;
+ case 'i': pmo_q_info = 1; break;
+ case 'o': pmo_q_owns = 1; break;
+ case 'u': pmo_s_upgrade = 1; break;
+ case 'w': pmo_s_downloadonly = 1; break;
+ case 'y': pmo_s_sync = 1; break;
+ case 's': pmo_s_search = 1; break;
+ case 'c': pmo_s_clean = 1; pmo_r_cascade = 1; break;
+ case 'r': if(realpath(optarg, pmo_root) == NULL) {
+ perror("bad root path");
+ return(1);
+ } break;
+ case '?': return(1);
+ default: return(1);
+ }
+ }
+
+ if(pmo_op == 0) {
+ fprintf(stderr, "error: only one operation may be used at a time\n\n");
+ return(1);
+ }
+
+ if(pmo_help) {
+ usage(pmo_op, (char*)basename(argv[0]));
+ return(2);
+ }
+ if(pmo_version) {
+ version();
+ return(2);
+ }
+
+ while(optind < argc) {
+ /* add the target to our target array */
+ char *s = strdup(argv[optind]);
+ pm_targets = list_add(pm_targets, s);
+ optind++;
+ }
+
+ return(0);
+}
+
+int parseconfig(char *configfile)
+{
+ FILE *fp = NULL;
+ char line[PATH_MAX+1];
+ char *ptr = NULL;
+ char *key = NULL;
+ int linenum = 0;
+ char section[256] = "";
+ sync_t *sync = NULL;
+
+ if((fp = fopen(configfile, "r")) == NULL) {
+ perror(configfile);
+ return(1);
+ }
+
+ while(fgets(line, PATH_MAX, fp)) {
+ linenum++;
+ trim(line);
+ if(strlen(line) == 0 || line[0] == '#') {
+ continue;
+ }
+ if(line[0] == '[' && line[strlen(line)-1] == ']') {
+ /* new config section */
+ ptr = line;
+ ptr++;
+ strncpy(section, ptr, min(255, strlen(ptr)-1));
+ section[min(255, strlen(ptr)-1)] = '\0';
+ vprint("config: new section '%s'\n", section);
+ if(!strlen(section)) {
+ fprintf(stderr, "config: line %d: bad section name\n", linenum);
+ return(1);
+ }
+ if(!strcmp(section, "local")) {
+ fprintf(stderr, "config: line %d: %s is reserved and cannot be used as a package tree\n",
+ linenum, section);
+ return(1);
+ }
+ if(strcmp(section, "options")) {
+ /* start a new sync record */
+ MALLOC(sync, sizeof(sync_t));
+ sync->treename = strdup(section);
+ sync->servers = NULL;
+ pmc_syncs = list_add(pmc_syncs, sync);
+ }
+ } else {
+ /* directive */
+ if(!strlen(section)) {
+ fprintf(stderr, "config: line %d: all directives must belong to a section\n", linenum);
+ return(1);
+ }
+ ptr = line;
+ key = strsep(&ptr, "=");
+ if(key == NULL) {
+ fprintf(stderr, "config: line %d: syntax error\n", linenum);
+ return(1);
+ }
+ trim(key);
+ key = strtoupper(key);
+ if(ptr == NULL) {
+ if(!strcmp(key, "NOPASSIVEFTP")) {
+ pmo_nopassiveftp = 1;
+ vprint("config: nopassiveftp\n");
+ } else {
+ fprintf(stderr, "config: line %d: syntax error\n", linenum);
+ return(1);
+ }
+ } else {
+ trim(ptr);
+ if(!strcmp(section, "options")) {
+ if(!strcmp(key, "NOUPGRADE")) {
+ char *p = ptr;
+ char *q;
+ while((q = strchr(p, ' '))) {
+ *q = '\0';
+ pmo_noupgrade = list_add(pmo_noupgrade, strdup(p));
+ vprint("config: noupgrade: %s\n", p);
+ p = q;
+ p++;
+ }
+ pmo_noupgrade = list_add(pmo_noupgrade, strdup(p));
+ vprint("config: noupgrade: %s\n", p);
+ } else if(!strcmp(key, "IGNOREPKG")) {
+ char *p = ptr;
+ char *q;
+ while((q = strchr(p, ' '))) {
+ *q = '\0';
+ pmo_ignorepkg = list_add(pmo_ignorepkg, strdup(p));
+ vprint("config: ignorepkg: %s\n", p);
+ p = q;
+ p++;
+ }
+ pmo_ignorepkg = list_add(pmo_ignorepkg, strdup(p));
+ vprint("config: ignorepkg: %s\n", p);
+ } else if(!strcmp(key, "DBPATH")) {
+ /* shave off the leading slash, if there is one */
+ if(*ptr == '/') {
+ ptr++;
+ }
+ strncpy(pmo_dbpath, ptr, PATH_MAX);
+ vprint("config: dbpath: %s\n", pmo_dbpath);
+ } else {
+ fprintf(stderr, "config: line %d: syntax error\n", linenum);
+ return(1);
+ }
+ } else {
+ if(!strcmp(key, "SERVER")) {
+ /* parse our special url */
+ server_t *server;
+ char *p;
+
+ MALLOC(server, sizeof(server_t));
+ server->server = server->path = NULL;
+ server->islocal = 0;
+
+ p = strstr(ptr, "://");
+ if(p == NULL) {
+ fprintf(stderr, "config: line %d: bad server location\n", linenum);
+ return(1);
+ }
+ *p = '\0';
+ p++; p++; p++;
+ if(p == NULL || *p == '\0') {
+ fprintf(stderr, "config: line %d: bad server location\n", linenum);
+ return(1);
+ }
+ server->islocal = !strcmp(ptr, "local");
+ if(!server->islocal) {
+ char *slash;
+ /* no http support yet */
+ if(strcmp(ptr, "ftp")) {
+ fprintf(stderr, "config: line %d: protocol %s is not supported\n", linenum, ptr);
+ return(1);
+ }
+ /* split the url into domain and path */
+ slash = strchr(p, '/');
+ if(slash == NULL) {
+ /* no path included, default to / */
+ server->path = strdup("/");
+ } else {
+ /* add a trailing slash if we need to */
+ if(slash[strlen(slash)-1] == '/') {
+ server->path = strdup(slash);
+ } else {
+ MALLOC(server->path, strlen(slash)+2);
+ sprintf(server->path, "%s/", slash);
+ }
+ *slash = '\0';
+ }
+ server->server = strdup(p);
+ } else {
+ /* add a trailing slash if we need to */
+ if(p[strlen(p)-1] == '/') {
+ server->path = strdup(p);
+ } else {
+ MALLOC(server->path, strlen(p)+2);
+ sprintf(server->path, "%s/", p);
+ }
+ }
+ /* add to the list */
+ vprint("config: %s: server: %s %s\n", section, server->server, server->path);
+ sync->servers = list_add(sync->servers, server);
+ } else {
+ fprintf(stderr, "config: line %d: syntax error\n", linenum);
+ return(1);
+ }
+ }
+ line[0] = '\0';
+ }
+ }
+ }
+ fclose(fp);
+
+ return(0);
+}
+
+/* Display usage/syntax for the specified operation.
+ * op: the operation code requested
+ * myname: basename(argv[0])
+ */
+void usage(int op, char *myname)
+{
+ if(op == PM_MAIN) {
+ printf("usage: %s {-h --help}\n", myname);
+ printf(" %s {-V --version}\n", myname);
+ printf(" %s {-A --add} [options] <file>\n", myname);
+ printf(" %s {-R --remove} [options] <package>\n", myname);
+ printf(" %s {-U --upgrade} [options] <file>\n", myname);
+ printf(" %s {-F --freshen} [options] <file>\n", myname);
+ printf(" %s {-Q --query} [options] [package]\n", myname);
+ printf(" %s {-S --sync} [options] [package]\n", myname);
+ printf("\nuse '%s --help' with other options for more syntax\n\n", myname);
+ } else {
+ if(op == PM_ADD) {
+ printf("usage: %s {-A --add} [options] <file>\n", myname);
+ printf("options:\n");
+ printf(" -d, --nodeps skip dependency checks\n");
+ printf(" -f, --force force install, overwrite conflicting files\n");
+ } else if(op == PM_REMOVE) {
+ printf("usage: %s {-R --remove} [options] <package>\n", myname);
+ printf("options:\n");
+ printf(" -c, --cascade remove packages and all packages that depend on them\n");
+ printf(" -d, --nodeps skip dependency checks\n");
+ printf(" -n, --nosave remove configuration files as well\n");
+ } else if(op == PM_UPGRADE) {
+ if(pmo_freshen) {
+ printf("usage: %s {-F --freshen} [options] <file>\n", myname);
+ } else {
+ printf("usage: %s {-U --upgrade} [options] <file>\n", myname);
+ }
+ printf("options:\n");
+ printf(" -d, --nodeps skip dependency checks\n");
+ printf(" -f, --force force install, overwrite conflicting files\n");
+ } else if(op == PM_QUERY) {
+ printf("usage: %s {-Q --query} [options] [package]\n", myname);
+ printf("options:\n");
+ printf(" -i, --info view package information\n");
+ printf(" -l, --list list the contents of the queried package\n");
+ printf(" -o, --owns <file> query the package that owns <file>\n");
+ printf(" -p, --file pacman will query the package file [package] instead of\n");
+ printf(" looking in the database\n");
+ } else if(op == PM_SYNC) {
+ printf("usage: %s {-S --sync} [options] [package]\n", myname);
+ printf("options:\n");
+ printf(" -c, --clean remove packages from cache directory to free up diskspace\n");
+ printf(" -d, --nodeps skip dependency checks\n");
+ printf(" -f, --force force install, overwrite conflicting files\n");
+ printf(" -s, --search search sync database for matching strings\n");
+ printf(" -u, --sysupgrade upgrade all packages that are out of date\n");
+ printf(" -w, --downloadonly download packages, but do not install/upgrade anything\n");
+ printf(" -y, --refresh download a fresh package sync database from the server\n");
+ }
+ printf(" -v, --verbose be verbose\n");
+ printf(" -r, --root <path> set an alternate installation root\n");
+ }
+}
+
+/* Version
+ */
+void version(void)
+{
+ printf("\n");
+ printf(" .--. Pacman v%s\n", PACVER);
+ printf("/ _.-' .-. .-. .-. Copyright (C) 2002 Judd Vinet <jvinet@zeroflux.org>\n");
+ printf("\\ '-. '-' '-' '-' \n");
+ printf(" '--' This program may be freely redistributed under\n");
+ printf(" the terms of the GNU GPL\n\n");
+}
+
+/* Check verbosity option and, if set, print the
+ * string to stdout
+ */
+int vprint(char *fmt, ...)
+{
+ va_list args;
+ if(pmo_verbose) {
+ va_start(args, fmt);
+ vprintf(fmt, args);
+ va_end(args);
+ fflush(stdout);
+ }
+ return(0);
+}
+
int lckmk(char *file, int retries, unsigned int sleep_secs)
{
int fd, count = 0;
@@ -1928,7 +2262,7 @@ int lckrm(char *file)
void cleanup(int signum)
{
- if(lckrm(lckfile)) {
+ if(pm_access == READ_WRITE && lckrm(lckfile)) {
fprintf(stderr, "warning: could not remove lock file %s\n", lckfile);
}
if(workfile) {
diff --git a/src/pacman.h b/src/pacman.h
index 0f70ffe2..5c1a94dd 100644
--- a/src/pacman.h
+++ b/src/pacman.h
@@ -22,7 +22,7 @@
#define _PAC_PACMAN_H
#ifndef PACVER
-#define PACVER "2.4.1"
+#define PACVER "2.5"
#endif
#ifndef PKGDIR
@@ -42,6 +42,8 @@
#define PM_SYNC 6
#define PM_DEPTEST 7
+#define min(X, Y) ((X) < (Y) ? (X) : (Y))
+
int pacman_add(pacdb_t *db, PMList *targets);
int pacman_remove(pacdb_t *db, PMList *targets);
int pacman_upgrade(pacdb_t *db, PMList *targets);
@@ -53,6 +55,14 @@ PMList* checkdeps(pacdb_t *db, unsigned short op, PMList *targets);
int resolvedeps(pacdb_t *local, PMList *databases, syncpkg_t *sync, PMList *list, PMList *trail);
int splitdep(char *depstr, depend_t *depend);
+char* needbackup(char *file, PMList *backup);
+
+int parseargs(int op, int argc, char **argv);
+int parseconfig(char *configfile);
+void usage(int op, char *myname);
+void version(void);
+
+int vprint(char *fmt, ...);
int lckmk(char *file, int retries, unsigned int sleep_secs);
int lckrm(char *lckfile);
void cleanup(int signum);
diff --git a/src/pacsync.c b/src/pacsync.c
index fce3a29b..da2f1a9a 100644
--- a/src/pacsync.c
+++ b/src/pacsync.c
@@ -21,11 +21,8 @@
#include "config.h"
#include <stdio.h>
-#include <stdlib.h>
-#include <limits.h>
-#include <errno.h>
#include <string.h>
-#include <sys/types.h>
+#include <sys/stat.h>
#include <unistd.h>
#include <ftplib.h>
/* pacman */
@@ -42,7 +39,7 @@ static int offset;
/* pacman options */
extern char *pmo_root;
-extern unsigned char pmo_nopassiveftp;
+extern unsigned short pmo_nopassiveftp;
/* sync servers */
extern PMList *pmc_syncs;
@@ -130,6 +127,13 @@ int downloadfiles(PMList *servers, char *localpath, PMList *files)
FtpLastResponse(control));
continue;
}
+ if(!pmo_nopassiveftp) {
+ if(!FtpOptions(FTPLIB_CONNMODE, FTPLIB_PASSIVE, control)) {
+ fprintf(stderr, "warning: failed to set passive mode\n");
+ }
+ } else {
+ vprint("FTP passive mode not set\n");
+ }
}
/* get each file in the list */
@@ -151,13 +155,6 @@ int downloadfiles(PMList *servers, char *localpath, PMList *files)
sync_fnm[24] = '\0';
if(!server->islocal) {
- if(!pmo_nopassiveftp) {
- if(!FtpOptions(FTPLIB_CONNMODE, FTPLIB_PASSIVE, control)) {
- fprintf(stderr, "warning: failed to set passive mode\n");
- }
- } else {
- vprint("FTP passive mode not set\n");
- }
if(!FtpSize(fn, &fsz, FTPLIB_IMAGE, control)) {
fprintf(stderr, "warning: failed to get filesize for %s\n", fn);
}
@@ -246,4 +243,23 @@ static int log_progress(netbuf *ctl, int xfered, void *arg)
return(1);
}
+/* Test for existence of a package in a PMList*
+ * of syncpkg_t*
+ */
+int is_pkginsync(syncpkg_t *needle, PMList *haystack)
+{
+ PMList *lp;
+ syncpkg_t *sync;
+ int found = 0;
+
+ for(lp = haystack; lp && !found; lp = lp->next) {
+ sync = (syncpkg_t*)lp->data;
+ if(sync && !strcmp(sync->pkg->name, needle->pkg->name)) {
+ found = 1;
+ }
+ }
+
+ return found;
+}
+
/* vim: set ts=2 sw=2 noet: */
diff --git a/src/pacsync.h b/src/pacsync.h
index 1838a684..abb657f8 100644
--- a/src/pacsync.h
+++ b/src/pacsync.h
@@ -21,12 +21,14 @@
#ifndef _PAC_PACSYNC_H
#define _PAC_PACSYNC_H
+/* Servers */
typedef struct __server_t {
unsigned short islocal;
char* server;
char* path;
} server_t;
+/* Repositories */
typedef struct __sync_t {
char* treename;
PMList *servers;
@@ -46,6 +48,7 @@ typedef struct __syncpkg_t {
int sync_synctree();
int downloadfiles(PMList *servers, char *localpath, PMList *files);
+int is_pkginsync(syncpkg_t *needle, PMList *haystack);
#endif
diff --git a/src/rpmvercmp.h b/src/rpmvercmp.h
new file mode 100644
index 00000000..3b7df650
--- /dev/null
+++ b/src/rpmvercmp.h
@@ -0,0 +1,28 @@
+/*
+ * pacman
+ *
+ * Copyright (c) 2002 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_RPMVERCMP_H
+#define _PAC_RPMVERCMP_H
+
+int rpmvercmp(const char *a, const char *b);
+
+#endif
+
+/* vim: set ts=2 sw=2 noet: */
diff --git a/src/util.c b/src/util.c
index 2b0aa0d9..cd7978e9 100644
--- a/src/util.c
+++ b/src/util.c
@@ -24,52 +24,16 @@
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
-#include <limits.h>
#include <errno.h>
#include <fcntl.h>
-#include <libgen.h>
-#include <getopt.h>
#include <ctype.h>
-#include "list.h"
-#include "package.h"
-#include "db.h"
+#include <dirent.h>
+#include <zlib.h>
+#include <libtar.h>
#include "util.h"
-#include "pacsync.h"
-#include "pacman.h"
-/* command line options */
-extern char* pmo_root;
-extern unsigned short pmo_op;
-extern unsigned short pmo_version;
-extern unsigned short pmo_verbose;
-extern unsigned short pmo_help;
-extern unsigned short pmo_force;
-extern unsigned short pmo_nodeps;
-extern unsigned short pmo_upgrade;
-extern unsigned short pmo_freshen;
-extern unsigned short pmo_nosave;
-extern unsigned short pmo_d_vertest;
-extern unsigned short pmo_d_resolve;
-extern unsigned short pmo_q_isfile;
-extern unsigned short pmo_q_info;
-extern unsigned short pmo_q_list;
-extern unsigned short pmo_q_owns;
-extern unsigned short pmo_r_cascade;
-extern unsigned short pmo_s_sync;
-extern unsigned short pmo_s_search;
-extern unsigned short pmo_s_clean;
-extern unsigned short pmo_s_upgrade;
-extern unsigned short pmo_s_downloadonly;
-/* configuration file options */
-extern PMList *pmo_noupgrade;
-extern PMList *pmo_ignorepkg;
-extern unsigned short pmo_nopassiveftp;
-
-extern PMList *pmc_syncs;
-extern PMList *pm_targets;
-
-/* borrowed and modifed from Per Liden's pkgutils (http://crux.nu) */
-static int gzopen_frontend(char *pathname, int oflags, int mode)
+/* borrowed and modified from Per Liden's pkgutils (http://crux.nu) */
+int gzopen_frontend(char *pathname, int oflags, int mode)
{
char* gzoflags;
int fd;
@@ -102,17 +66,16 @@ static int gzopen_frontend(char *pathname, int oflags, int mode)
return (int)gzf;
}
-tartype_t gztype = {
- (openfunc_t) gzopen_frontend,
- (closefunc_t)gzclose,
- (readfunc_t) gzread,
- (writefunc_t)gzwrite
-};
-
int unpack(char *archive, char *prefix)
{
TAR *tar = NULL;
char expath[PATH_MAX];
+ tartype_t gztype = {
+ (openfunc_t) gzopen_frontend,
+ (closefunc_t)gzclose,
+ (readfunc_t) gzread,
+ (writefunc_t)gzwrite
+ };
/* open the .tar.gz package */
if(tar_open(&tar, archive, &gztype, O_RDONLY, 0, TAR_GNU) == -1) {
@@ -130,280 +93,6 @@ int unpack(char *archive, char *prefix)
return(0);
}
-/* Parse command-line arguments for each operation
- * op: the operation code requested
- * argc: argc
- * argv: argv
- *
- * Returns: 0 on success, 1 on error
- */
-int parseargs(int op, int argc, char **argv)
-{
- int opt;
- int option_index = 0;
- static struct option opts[] =
- {
- {"add", no_argument, 0, 'A'},
- {"remove", no_argument, 0, 'R'},
- {"upgrade", no_argument, 0, 'U'},
- {"freshen", no_argument, 0, 'F'},
- {"query", no_argument, 0, 'Q'},
- {"sync", no_argument, 0, 'S'},
- {"deptest", no_argument, 0, 'T'},
- {"vertest", no_argument, 0, 'Y'},
- {"resolve", no_argument, 0, 'D'},
- {"root", required_argument, 0, 'r'},
- {"verbose", no_argument, 0, 'v'},
- {"version", no_argument, 0, 'V'},
- {"help", no_argument, 0, 'h'},
- {"search", no_argument, 0, 's'},
- {"clean", no_argument, 0, 'c'},
- {"force", no_argument, 0, 'f'},
- {"nodeps", no_argument, 0, 'd'},
- {"nosave", no_argument, 0, 'n'},
- {"owns", no_argument, 0, 'o'},
- {"list", no_argument, 0, 'l'},
- {"file", no_argument, 0, 'p'},
- {"info", no_argument, 0, 'i'},
- {"sysupgrade", no_argument, 0, 'u'},
- {"downloadonly", no_argument, 0, 'w'},
- {"refresh", no_argument, 0, 'y'},
- {"cascade", no_argument, 0, 'c'},
- {0, 0, 0, 0}
- };
-
- while((opt = getopt_long(argc, argv, "ARUFQSTDYr:vhscVfnoldpiuwy", opts, &option_index))) {
- if(opt < 0) {
- break;
- }
- switch(opt) {
- case 0: break;
- case 'A': pmo_op = (pmo_op != PM_MAIN ? 0 : PM_ADD); break;
- case 'R': pmo_op = (pmo_op != PM_MAIN ? 0 : PM_REMOVE); break;
- case 'U': pmo_op = (pmo_op != PM_MAIN ? 0 : PM_UPGRADE); break;
- case 'F': pmo_op = (pmo_op != PM_MAIN ? 0 : PM_UPGRADE); pmo_freshen = 1; break;
- case 'Q': pmo_op = (pmo_op != PM_MAIN ? 0 : PM_QUERY); break;
- case 'S': pmo_op = (pmo_op != PM_MAIN ? 0 : PM_SYNC); break;
- case 'T': pmo_op = (pmo_op != PM_MAIN ? 0 : PM_DEPTEST); break;
- case 'Y': pmo_op = (pmo_op != PM_MAIN ? 0 : PM_DEPTEST); pmo_d_vertest = 1; break;
- case 'D': pmo_op = (pmo_op != PM_MAIN ? 0 : PM_DEPTEST); pmo_d_resolve = 1; break;
- case 'h': pmo_help = 1; break;
- case 'V': pmo_version = 1; break;
- case 'v': pmo_verbose = 1; break;
- case 'f': pmo_force = 1; break;
- case 'd': pmo_nodeps = 1; break;
- case 'n': pmo_nosave = 1; break;
- case 'l': pmo_q_list = 1; break;
- case 'p': pmo_q_isfile = 1; break;
- case 'i': pmo_q_info = 1; break;
- case 'o': pmo_q_owns = 1; break;
- case 'u': pmo_s_upgrade = 1; break;
- case 'w': pmo_s_downloadonly = 1; break;
- case 'y': pmo_s_sync = 1; break;
- case 's': pmo_s_search = 1; break;
- case 'c': pmo_s_clean = 1; pmo_r_cascade = 1; break;
- case 'r': if(realpath(optarg, pmo_root) == NULL) {
- perror("bad root path");
- return(1);
- } break;
- case '?': return(1);
- default: return(1);
- }
- }
-
- if(pmo_op == 0) {
- fprintf(stderr, "error: only one operation may be used at a time\n\n");
- return(1);
- }
-
- if(pmo_help) {
- usage(pmo_op, (char*)basename(argv[0]));
- return(2);
- }
- if(pmo_version) {
- version();
- return(2);
- }
-
- while(optind < argc) {
- /* add the target to our target array */
- char *s = strdup(argv[optind]);
- pm_targets = list_add(pm_targets, s);
- optind++;
- }
-
- return(0);
-}
-
-#define min(X, Y) ((X) < (Y) ? (X) : (Y))
-int parseconfig(char *configfile)
-{
- FILE *fp = NULL;
- char line[PATH_MAX+1];
- char *ptr = NULL;
- char *key = NULL;
- int linenum = 0;
- char section[256] = "";
- sync_t *sync = NULL;
-
- if((fp = fopen(configfile, "r")) == NULL) {
- perror(configfile);
- return(1);
- }
-
- while(fgets(line, PATH_MAX, fp)) {
- linenum++;
- trim(line);
- if(strlen(line) == 0 || line[0] == '#') {
- continue;
- }
- if(line[0] == '[' && line[strlen(line)-1] == ']') {
- /* new config section */
- ptr = line;
- ptr++;
- strncpy(section, ptr, min(255, strlen(ptr)-1));
- section[min(255, strlen(ptr)-1)] = '\0';
- vprint("config: new section '%s'\n", section);
- if(!strlen(section)) {
- fprintf(stderr, "config: line %d: bad section name\n", linenum);
- return(1);
- }
- if(!strcmp(section, "local")) {
- fprintf(stderr, "config: line %d: %s is reserved and cannot be used as a package tree\n",
- linenum, section);
- return(1);
- }
- if(strcmp(section, "options")) {
- /* start a new sync record */
- MALLOC(sync, sizeof(sync_t));
- sync->treename = strdup(section);
- sync->servers = NULL;
- pmc_syncs = list_add(pmc_syncs, sync);
- }
- } else {
- /* directive */
- if(!strlen(section)) {
- fprintf(stderr, "config: line %d: all directives must belong to a section\n", linenum);
- return(1);
- }
- ptr = line;
- key = strsep(&ptr, "=");
- if(key == NULL) {
- fprintf(stderr, "config: line %d: syntax error\n", linenum);
- return(1);
- }
- trim(key);
- key = strtoupper(key);
- if(ptr == NULL) {
- if(!strcmp(key, "NOPASSIVEFTP")) {
- pmo_nopassiveftp = 1;
- vprint("config: nopassiveftp\n");
- } else {
- fprintf(stderr, "config: line %d: syntax error\n", linenum);
- return(1);
- }
- } else {
- trim(ptr);
- if(!strcmp(section, "options")) {
- if(!strcmp(key, "NOUPGRADE")) {
- char *p = ptr;
- char *q;
- while((q = strchr(p, ' '))) {
- *q = '\0';
- pmo_noupgrade = list_add(pmo_noupgrade, strdup(p));
- vprint("config: noupgrade: %s\n", p);
- p = q;
- p++;
- }
- pmo_noupgrade = list_add(pmo_noupgrade, strdup(p));
- vprint("config: noupgrade: %s\n", p);
- } else if(!strcmp(key, "IGNOREPKG")) {
- char *p = ptr;
- char *q;
- while((q = strchr(p, ' '))) {
- *q = '\0';
- pmo_ignorepkg = list_add(pmo_ignorepkg, strdup(p));
- vprint("config: ignorepkg: %s\n", p);
- p = q;
- p++;
- }
- pmo_ignorepkg = list_add(pmo_ignorepkg, strdup(p));
- vprint("config: ignorepkg: %s\n", p);
- } else {
- fprintf(stderr, "config: line %d: syntax error\n", linenum);
- return(1);
- }
- } else {
- if(!strcmp(key, "SERVER")) {
- /* parse our special url */
- server_t *server;
- char *p;
-
- MALLOC(server, sizeof(server_t));
- server->server = server->path = NULL;
- server->islocal = 0;
-
- p = strstr(ptr, "://");
- if(p == NULL) {
- fprintf(stderr, "config: line %d: bad server location\n", linenum);
- return(1);
- }
- *p = '\0';
- p++; p++; p++;
- if(p == NULL || *p == '\0') {
- fprintf(stderr, "config: line %d: bad server location\n", linenum);
- return(1);
- }
- server->islocal = !strcmp(ptr, "local");
- if(!server->islocal) {
- char *slash;
- /* no http support yet */
- if(strcmp(ptr, "ftp")) {
- fprintf(stderr, "config: line %d: protocol %s is not supported\n", linenum, ptr);
- return(1);
- }
- /* split the url into domain and path */
- slash = strchr(p, '/');
- if(slash == NULL) {
- /* no path included, default to / */
- server->path = strdup("/");
- } else {
- /* add a trailing slash if we need to */
- if(slash[strlen(slash)-1] == '/') {
- server->path = strdup(slash);
- } else {
- MALLOC(server->path, strlen(slash)+2);
- sprintf(server->path, "%s/", slash);
- }
- *slash = '\0';
- }
- server->server = strdup(p);
- } else {
- /* add a trailing slash if we need to */
- if(p[strlen(p)-1] == '/') {
- server->path = strdup(p);
- } else {
- MALLOC(server->path, strlen(p)+2);
- sprintf(server->path, "%s/", p);
- }
- }
- /* add to the list */
- vprint("config: %s: server: %s %s\n", section, server->server, server->path);
- sync->servers = list_add(sync->servers, server);
- } else {
- fprintf(stderr, "config: line %d: syntax error\n", linenum);
- return(1);
- }
- }
- line[0] = '\0';
- }
- }
- }
- fclose(fp);
-
- return(0);
-}
-
int copyfile(char *src, char *dest)
{
FILE *in, *out;
@@ -501,94 +190,6 @@ int rmrf(char *path)
return(0);
}
-/* Display usage/syntax for the specified operation.
- * op: the operation code requested
- * myname: basename(argv[0])
- */
-void usage(int op, char *myname)
-{
- if(op == PM_MAIN) {
- printf("usage: %s {-h --help}\n", myname);
- printf(" %s {-V --version}\n", myname);
- printf(" %s {-A --add} [options] <file>\n", myname);
- printf(" %s {-R --remove} [options] <package>\n", myname);
- printf(" %s {-U --upgrade} [options] <file>\n", myname);
- printf(" %s {-F --freshen} [options] <file>\n", myname);
- printf(" %s {-Q --query} [options] [package]\n", myname);
- printf(" %s {-S --sync} [options] [package]\n", myname);
- printf("\nuse '%s --help' with other options for more syntax\n\n", myname);
- } else {
- if(op == PM_ADD) {
- printf("usage: %s {-A --add} [options] <file>\n", myname);
- printf("options:\n");
- printf(" -f, --force force install, overwrite conflicting files\n");
- printf(" -d, --nodeps skip dependency checks\n");
- } else if(op == PM_REMOVE) {
- printf("usage: %s {-R --remove} [options] <package>\n", myname);
- printf("options:\n");
- printf(" -d, --nodeps skip dependency checks\n");
- printf(" -n, --nosave remove configuration files as well\n");
- printf(" -c, --cascade remove packages and all packages that depend on them\n");
- } else if(op == PM_UPGRADE) {
- if(pmo_freshen) {
- printf("usage: %s {-F --freshen} [options] <file>\n", myname);
- } else {
- printf("usage: %s {-U --upgrade} [options] <file>\n", myname);
- }
- printf("options:\n");
- printf(" -f, --force force install, overwrite conflicting files\n");
- printf(" -d, --nodeps skip dependency checks\n");
- } else if(op == PM_QUERY) {
- printf("usage: %s {-Q --query} [options] [package]\n", myname);
- printf("options:\n");
- printf(" -o, --owns <file> query the package that owns <file>\n");
- printf(" -l, --list list the contents of the queried package\n");
- printf(" -i, --info view package information\n");
- printf(" -p, --file pacman will query the package file [package] instead of\n");
- printf(" looking in the database\n");
- } else if(op == PM_SYNC) {
- printf("usage: %s {-S --sync} [options] [package]\n", myname);
- printf("options:\n");
- printf(" -s, --search search sync database for matching strings\n");
- printf(" -f, --force force install, overwrite conflicting files\n");
- printf(" -d, --nodeps skip dependency checks\n");
- printf(" -y, --refresh download a fresh package sync database from the server\n");
- printf(" -u, --sysupgrade upgrade all packages that are out of date\n");
- printf(" -w, --downloadonly download packages, but do not install/upgrade anything\n");
- printf(" -c, --clean remove packages from cache directory to free up diskspace\n");
- }
- printf(" -v, --verbose be verbose\n");
- printf(" -r, --root <path> set an alternate installation root\n");
- }
-}
-
-/* Version
- */
-void version(void)
-{
- printf("\n");
- printf(" .--. Pacman v%s\n", PACVER);
- printf("/ _.-' .-. .-. .-. Copyright (C) 2002 Judd Vinet <jvinet@zeroflux.org>\n");
- printf("\\ '-. '-' '-' '-' \n");
- printf(" '--' This program may be freely redistributed under\n");
- printf(" the terms of the GNU GPL\n\n");
-}
-
-/* Check verbosity option and, if set, print the
- * string to stdout
- */
-int vprint(char *fmt, ...)
-{
- va_list args;
- if(pmo_verbose) {
- va_start(args, fmt);
- vprintf(fmt, args);
- va_end(args);
- fflush(stdout);
- }
- return(0);
-}
-
int yesno(char *fmt, ...)
{
char response[32];
@@ -651,76 +252,6 @@ void indentprint(char *str, int indent)
}
}
-/* Test for existence of a string in a PMList
- */
-int is_in(char *needle, PMList *haystack)
-{
- PMList *lp;
-
- for(lp = haystack; lp; lp = lp->next) {
- if(lp->data && !strcmp(lp->data, needle)) {
- return(1);
- }
- }
- return(0);
-}
-
-
-/* Look for a filename in a pkginfo_t.backup list. If we find it,
- * then we return the md5 hash (parsed from the same line)
- */
-char* needbackup(char* file, PMList *backup)
-{
- PMList *lp;
-
- /* run through the backup list and parse out the md5 hash for our file */
- for(lp = backup; lp; lp = lp->next) {
- char* str = strdup(lp->data);
- char* ptr;
-
- /* tab delimiter */
- ptr = index(str, '\t');
- if(ptr == NULL) {
- FREE(str);
- continue;
- }
- *ptr = '\0';
- ptr++;
- /* now str points to the filename and ptr points to the md5 hash */
- if(!strcmp(file, str)) {
- char *md5 = strdup(ptr);
- FREE(str);
- return(md5);
- }
- FREE(str);
- }
- return(NULL);
-}
-
-/* Test for existence of a package in a PMList*
- * of pkginfo_t*
- *
- * returns: 0 for no match
- * 1 for identical match
- * -1 for name-only match (version mismatch)
- */
-int is_pkgin(pkginfo_t *needle, PMList *haystack)
-{
- PMList *lp;
- pkginfo_t *info;
-
- for(lp = haystack; lp; lp = lp->next) {
- info = (pkginfo_t*)lp->data;
- if(info && !strcmp(info->name, needle->name)) {
- if(!strcmp(info->version, needle->version)) {
- return(1);
- }
- return(-1);
- }
- }
- return(0);
-}
-
/* Convert a string to uppercase
*/
char* strtoupper(char *str)
diff --git a/src/util.h b/src/util.h
index 222c00fa..be2c6089 100644
--- a/src/util.h
+++ b/src/util.h
@@ -21,30 +21,20 @@
#ifndef _PAC_UTIL_H
#define _PAC_UTIL_H
-#include <libtar.h>
-#include <zlib.h>
-
#define MALLOC(p, b) { if((b) > 0) { \
p = malloc(b); if (!(p)) { \
- fprintf(stderr, "malloc failure: could not allocate %d byets\n", b); \
+ fprintf(stderr, "malloc failure: could not allocate %d bytes\n", b); \
exit(1); }} else p = NULL; }
#define FREE(p) { if (p) { free(p); (p)= NULL; }}
+int gzopen_frontend(char *pathname, int oflags, int mode);
int unpack(char *archive, char *prefix);
-int parseargs(int op, int argc, char **argv);
-int parseconfig(char *configfile);
int copyfile(char *src, char *dest);
int makepath(char *path);
int rmrf(char *path);
-int vprint(char *fmt, ...);
void indentprint(char *str, int indent);
int yesno(char* fmt, ...);
-void usage(int op, char *myname);
-void version(void);
-char* needbackup(char *file, PMList *backup);
-int is_in(char *needle, PMList *haystack);
-int is_pkgin(pkginfo_t *needle, PMList *haystack);
char* trim(char *str);
char* strtoupper(char *str);
diff --git a/src/vercmp.c b/src/vercmp.c
index 850ebea6..43f8deab 100644
--- a/src/vercmp.c
+++ b/src/vercmp.c
@@ -1,7 +1,27 @@
+/*
+ * pacman
+ *
+ * Copyright (c) 2002 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.
+ */
+
#include <stdio.h>
#include <string.h>
-
-int rpmvercmp(const char *a, const char *b);
+#include "rpmvercmp.h"
int main(int argc, char *argv[])
{