Imported from pacman-2.5.tar.gz
This commit is contained in:
parent
e9c6f3b213
commit
636c641119
25 changed files with 1270 additions and 1106 deletions
10
ChangeLog
10
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
|
||||
|
|
21
Makefile.in
21
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 $<
|
||||
|
|
19
cnvpkg
Executable file
19
cnvpkg
Executable file
|
@ -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
|
|
@ -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)
|
||||
|
@ -186,6 +187,11 @@ This is the release number specific to Arch Linux packages.
|
|||
.B pkgdesc
|
||||
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
|
||||
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#!/bin/bash
|
||||
|
||||
myver='2.4.1'
|
||||
myver='2.5'
|
||||
|
||||
usage() {
|
||||
echo "gensync $myver"
|
||||
|
|
500
scripts/makepkg
500
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
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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: */
|
||||
|
|
81
src/db.c
81
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) {
|
||||
|
|
5
src/db.h
5
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: */
|
||||
|
|
94
src/list.c
94
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: */
|
||||
|
|
24
src/list.h
24
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
|
||||
|
||||
|
|
|
@ -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: */
|
||||
|
|
|
@ -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
|
||||
|
|
129
src/package.c
129
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: */
|
||||
|
|
|
@ -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: */
|
||||
|
|
696
src/pacman.c
696
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) {
|
||||
|
|
12
src/pacman.h
12
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);
|
||||
|
|
|
@ -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: */
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
28
src/rpmvercmp.h
Normal file
28
src/rpmvercmp.h
Normal file
|
@ -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: */
|
491
src/util.c
491
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)
|
||||
|
|
14
src/util.h
14
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);
|
||||
|
||||
|
|
24
src/vercmp.c
24
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[])
|
||||
{
|
||||
|
|
Loading…
Add table
Reference in a new issue