From f2e50be2f5b15c1985f9fcfb7ee1374dd6e94927 Mon Sep 17 00:00:00 2001 From: Judd Vinet Date: Thu, 27 Feb 2003 08:26:02 +0000 Subject: Imported from pacman-2.3.tar.gz --- Makefile.in | 15 ++-- README | 21 +++--- TODO | 29 ++++---- doc/makepkg.8.in | 25 ++++++- doc/pacman.8.in | 6 +- etc/makepkg.conf | 19 ++++- etc/pacman.conf | 44 +++++++---- etc/supfile.arch | 23 ------ etc/supfile.unofficial | 16 ---- scripts/abs | 51 ------------- scripts/gensync | 2 +- scripts/makepkg | 197 ++++++++++++++++++++++++++++++++++++++----------- scripts/makeworld | 24 +++++- scripts/pacsync | 6 -- src/pacman.c | 110 ++++++++++++++++++++------- src/pacman.h | 6 +- src/util.c | 91 ++++++++++++++++++----- src/util.h | 1 + src/vercmp.c | 25 +++++++ 19 files changed, 470 insertions(+), 241 deletions(-) delete mode 100644 etc/supfile.arch delete mode 100644 etc/supfile.unofficial delete mode 100755 scripts/abs delete mode 100755 scripts/pacsync create mode 100644 src/vercmp.c diff --git a/Makefile.in b/Makefile.in index 18a44543..90a72ffa 100644 --- a/Makefile.in +++ b/Makefile.in @@ -34,7 +34,7 @@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS) INSTALL_DATA = @INSTALL_DATA@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ -PACVER = 2.2 +PACVER = 2.3 LIBTAR_VERSION = 1.2.5 TOPDIR = @srcdir@ @@ -70,11 +70,14 @@ OBJECTS = $(OBJDIR)pacman.o \ $(OBJDIR)md5.o \ $(OBJDIR)md5driver.o -all: libtar ftplib pacman convertdb man +all: libtar 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 $@ + convertdb: $(SRCDIR)convertdb.c $(SRCDIR)list.c $(CXX) -o convertdb $(SRCDIR)convertdb.c $(SRCDIR)list.c $(CXXFLAGS) @@ -99,26 +102,24 @@ libtar: LDFLAGS="" ./configure --disable-encap --disable-encap-install; \ make;) -install: pacman convertdb man +install: pacman vercmp convertdb man $(INSTALL) -D -m0755 pacman $(DESTDIR)$(BINDIR)/pacman + $(INSTALL) -D -m0755 vercmp $(DESTDIR)$(BINDIR)/vercmp $(INSTALL) -D -m0755 convertdb $(DESTDIR)$(BINDIR)/convertdb $(INSTALL) -D -m0755 $(SCRDIR)makepkg $(DESTDIR)$(BINDIR)/makepkg $(INSTALL) -D -m0755 $(SCRDIR)makeworld $(DESTDIR)$(BINDIR)/makeworld - $(INSTALL) -D -m0755 $(SCRDIR)abs $(DESTDIR)$(BINDIR)/abs $(INSTALL) -D -m0755 $(SCRDIR)gensync $(DESTDIR)$(BINDIR)/gensync $(INSTALL) -D -m0644 $(MANSRC)pacman.8 $(DESTDIR)$(MANDIR)/man8/pacman.8 $(INSTALL) -D -m0644 $(MANSRC)makepkg.8 $(DESTDIR)$(MANDIR)/man8/makepkg.8 $(INSTALL) -D -m0644 etc/pacman.conf $(DESTDIR)/etc/pacman.conf $(INSTALL) -D -m0644 etc/makepkg.conf $(DESTDIR)/etc/makepkg.conf - $(INSTALL) -D -m0644 etc/supfile.arch $(DESTDIR)/etc/abs/supfile.arch - $(INSTALL) -D -m0644 etc/supfile.unofficial $(DESTDIR)/etc/abs/supfile.unofficial clean: rm -f *~ $(OBJDIR)*.o $(MANSRC)*.8 (cd libftp; make clobber) distclean: clean - rm -f pacman convertdb + rm -f pacman convertdb vercmp rm -rf libtar-$(LIBTAR_VERSION) # End of file diff --git a/README b/README index df24ed93..a5528c6e 100644 --- a/README +++ b/README @@ -8,12 +8,13 @@ DESCRIPTION: pacman is a utility which manages software packages in Linux. It uses simple .tar.gz files as a package format, and maintains a text-based package database (more of a hierarchy), just in case some hand tweaking - is necessary. + is necessary. pacman does not strive to "do everything." It will add, remove and upgrade packages in the system, and it will allow you to query the package database for installed packages, files and owners. It also - attempts to handle dependencies automatically and can + attempts to handle dependencies automatically and can download packages + from a remote server. Although the package manager itself is quite simple, the pacman tarball also comes with scripts that help automate building and installing @@ -21,16 +22,16 @@ DESCRIPTION: used in Arch Linux . As of version 2.0, pacman can also keep your system's packages in - sync with a master server. You can follow CURRENT and STABLE trees, - or lock yourself into a specific version. See the pacman manpage - for more info on this (--sync operation). + sync with a master server. You can follow CURRENT and STABLE trees, + or lock yourself into a specific version. See the pacman manpage + for more info on this (--sync operation). INSTALL: -------- -$ make install -or -$ make DESTDIR=/your/path/here install +$ ./configure +$ make +# make install If your man files are located in a directory other than /usr/man, you may want to edit Makefile and modify the MANDIR line accordingly. @@ -42,7 +43,7 @@ Note: Since pacman is compiled statically, you will need the static libraries BUGS: ----- If you find bugs (which is quite likely), please submit them to - with specific information, such as your + with specific information such as your commandline, the nature of the bug, and even the package database if it helps. @@ -54,7 +55,7 @@ licensed through the GNU General Public License (see COPYING). pacman uses "libtar", a library for reading/writing tar-files. This library is Copyright (c) 1998-2001 Mark D. Roth (see -libtar-X.X.X/COPYRIGHT for further details). +libtar-X.X.X/COPYRIGHT for furthur details). pacman uses "ftplib", a library for sending/receiving files via FTP. This library is copyright (c) 1996-2000 Thomas Pfau, pfau@cnj.digex.net (see diff --git a/TODO b/TODO index e6b69f68..475705fe 100644 --- a/TODO +++ b/TODO @@ -1,30 +1,31 @@ +- add some logging mechanism (/var/log/pacman.log) +- handle version comparators in makepkg dep resolution (eg, glibc>=2.2.5) +- record md5sums of all files in a package - add a way to clean /var/cache/pacman/src -- add other options to config file: db location, overwrite behaviour, etc. -- don't skip the db update when a package fails to upgrade - we lose the entry +- duplicate dep checks occur with sync (one in sync, one in add) +- if a package is removed with --nodeps and re-installed, the requiredby + fields of it's required packages are not updated - have "group" designations +- IgnorePkg option in pacman.conf to ignore updates from the sync repo +- add an option equivalent to 'pacman -Ql pkg | grep filename' +- ftp transfer progress bar breaks after ~42000 K +- add other options to config file: db location, overwrite behaviour, etc. +- use the COLUMNS env var for the progress bar ? use 'set -e' in makepkg? x if a package fails, ask before aborting the full operation - can't -- further dependent packages may fail b/c of the first failure ? ask, then remove conflicting packages with --sync ? use a provides tag (instead of an OR operator in depends) -- add a freshen operation - add a 'cascade' option to --remove that will remove a package and all requiredby packages under it - check $PACCONF env var -- ftp transfer progress bar breaks after ~42000 K ? use a 'trust pacman' config option for downgrading? -- instead of 'conflicts' use a ! operator in depends +? build-time (source) dependencies in makepkg +? run ldd on every executable in a newly built package to find required so's - add a --pretend option -- add a consistency/sanity check operation +- add a consistency/sanity check operation (md5 tracking for all files) - add a --dbpath option -? build-time (source) dependencies in makepkg -- auto-resolve dependencies in makepkg - use package caches more for performance -- IgnorePkg option in pacman.conf to ignore updates from the sync repo -- if a package is removed with --nodeps and re-installed, the requiredby - fields of it's required packages are not updated -- duplicate dep checks occur with sync (one in sync, one in add) - clean up output a bit (message queue?) -? run ldd on every executable in a newly built package to find required so's -- use a files.cache gdbm (or whatever) for --owns and db_find_conflicts +- use a files.cache db for --owns and db_find_conflicts diff --git a/doc/makepkg.8.in b/doc/makepkg.8.in index bb2b313e..3cc60b2d 100644 --- a/doc/makepkg.8.in +++ b/doc/makepkg.8.in @@ -1,4 +1,4 @@ -.TH makepkg 8 "November 7, 2002" "makepkg #VERSION#" "" +.TH makepkg 8 "February 18, 2003" "makepkg #VERSION#" "" .SH NAME makepkg \- package build utility .SH SYNOPSIS @@ -231,6 +231,29 @@ Clean up leftover work files/directories after a successful build. .TP .B "\-i, \-\-install" Install/Upgrade the package after a successful build. +.TP +.B "\-d, \-\-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 +$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 "\-n, \-\-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 +process if all of the dependencies aren't installed. +.TP +.B "\-f, \-\-force" +\fBmakepkg\fP will not build a package if a \fIpkgname-pkgver-pkgrel.pkg.tar.gz\fP +file already exists in the build directory. You can override this behaviour with +the \fB--force\fP switch. .SH CONFIGURATION Configuration options are stored in \fI/etc/makepkg.conf\fP. This file is parsed diff --git a/doc/pacman.8.in b/doc/pacman.8.in index db72e5ff..b2211142 100644 --- a/doc/pacman.8.in +++ b/doc/pacman.8.in @@ -1,4 +1,4 @@ -.TH pacman 8 "November 7, 2002" "pacman #VERSION#" "" +.TH pacman 8 "January 20, 2003" "pacman #VERSION#" "" .SH NAME pacman \- package manager utility .SH SYNOPSIS @@ -26,6 +26,10 @@ 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. +.TP .B "\-Q, \-\-query" Query the package database. This operation allows you to view installed packages and their files, as well as meta-info diff --git a/etc/makepkg.conf b/etc/makepkg.conf index 375851f3..c73d9889 100644 --- a/etc/makepkg.conf +++ b/etc/makepkg.conf @@ -2,8 +2,23 @@ # /etc/makepkg.conf # -export CFLAGS="-O2 -march=i686 -pipe" -export CXXFLAGS="-O2 -march=i686 -pipe" +# the top-level directory of all your PKGBUILDs +export ABSROOT="/usr/abs" +# Pentium Pro/Pentium II/Pentium III+/Pentium 4/Athlon optimized (but binaries +# will run on any x86 system) +#export CHOST="i686-pc-linux-gnu" +#export CFLAGS="-mcpu=i686 -O2 -pipe" +#export CXXFLAGS="-mcpu=i686 -O2 -pipe" + +# Pentium Pro/Pentium II/Pentium III+/Pentium 4/Athlon exclusive (binaries +# will use the P6 instruction set and only run on P6+ systems) +export CHOST="i686-pc-linux-gnu" +export CFLAGS="-march=i686 -O2 -pipe" +export CXXFLAGS="-march=i686 -O2 -pipe" + +# SMP Systems #export MAKEFLAGS="-j 2" +# if you want your name to show up in the packages you build, set this. +#export PACKAGER="John Doe " diff --git a/etc/pacman.conf b/etc/pacman.conf index 491520b2..ad77cfec 100644 --- a/etc/pacman.conf +++ b/etc/pacman.conf @@ -8,42 +8,58 @@ [options] NoUpgrade = etc/passwd etc/group etc/shadow NoUpgrade = etc/fstab etc/rc.conf etc/rc.local -NoUpgrade = etc/lilo.conf +NoUpgrade = etc/lilo.conf etc/raidtab [current] +Server = ftp://ftp.archlinux.org/current Server = ftp://ftp.ibiblio.org/pub/linux/distributions/archlinux/current Server = ftp://ftp.webtrek.com/pub/mirrors/archlinux/current Server = ftp://ftp.mpi-sb.mpg.de/pub/linux/mirror/ftp.ibiblio.org/pub/Linux/distributions/archlinux/current Server = ftp://ftp.oit.unc.edu/pub/Linux/distributions/archlinux/current Server = ftp://ftp.tu-chemnitz.de/pub/linux/sunsite.unc-mirror/distributions/archlinux/current -Server = ftp://ftp.archlinux.org/current Server = ftp://gd.tuwien.ac.at/opsys/linux/archlinux/current Server = ftp://saule.mintis.lt/pub/linux/current +Server = ftp://ftp.rez-gif.supelec.fr/pub/Linux/distrib/archlinux/current + +# If you use the 'stable' tree, you should disable the 'current' +# tree to avoid conflicts +# +#[stable] +#Server = ftp://ftp.archlinux.org/stable +#Server = ftp://ftp.ibiblio.org/pub/linux/distributions/archlinux/stable +#Server = ftp://ftp.webtrek.com/pub/mirrors/archlinux/stable +#Server = ftp://ftp.mpi-sb.mpg.de/pub/linux/mirror/ftp.ibiblio.org/pub/Linux/distributions/archlinux/stable +#Server = ftp://ftp.oit.unc.edu/pub/Linux/distributions/archlinux/stable +#Server = ftp://ftp.tu-chemnitz.de/pub/linux/sunsite.unc-mirror/distributions/archlinux/stable +#Server = ftp://gd.tuwien.ac.at/opsys/linux/archlinux/stable +#Server = ftp://saule.mintis.lt/pub/linux/stable +#Server = ftp://ftp.rez-gif.supelec.fr/pub/Linux/distrib/archlinux/stable # Uncomment this block to access the 'unofficial' package set # #[unofficial] #Server = ftp://ftp.ibiblio.org/pub/linux/distributions/archlinux/unofficial #Server = ftp://ftp.webtrek.com/pub/mirrors/archlinux/unofficial +#Server = ftp://ftp.archlinux.org/unofficial #Server = ftp://ftp.mpi-sb.mpg.de/pub/linux/mirror/ftp.ibiblio.org/pub/Linux/distributions/archlinux/unofficial #Server = ftp://ftp.oit.unc.edu/pub/Linux/distributions/archlinux/unofficial #Server = ftp://ftp.tu-chemnitz.de/pub/linux/sunsite.unc-mirror/distributions/archlinux/unofficial -#Server = ftp://ftp.archlinux.org/unofficial #Server = ftp://gd.tuwien.ac.at/opsys/linux/archlinux/unofficial #Server = ftp://saule.mintis.lt/pub/linux/unofficial +#Server = ftp://ftp.rez-gif.supelec.fr/pub/Linux/distrib/archlinux/unofficial -# If you use the 'stable' tree, you should disable the 'current' -# tree to avoid conflicts +# Uncomment this block to access the 'unstable' package set # -#[stable] -#Server = ftp://ftp.ibiblio.org/pub/linux/distributions/archlinux/stable -#Server = ftp://ftp.webtrek.com/pub/mirrors/archlinux/stable -#Server = ftp://ftp.mpi-sb.mpg.de/pub/linux/mirror/ftp.ibiblio.org/pub/Linux/distributions/archlinux/stable -#Server = ftp://ftp.oit.unc.edu/pub/Linux/distributions/archlinux/stable -#Server = ftp://ftp.tu-chemnitz.de/pub/linux/sunsite.unc-mirror/distributions/archlinux/stable -#Server = ftp://ftp.archlinux.org/stable -#Server = ftp://gd.tuwien.ac.at/opsys/linux/archlinux/stable -#Server = ftp://saule.mintis.lt/pub/linux/stable +#[unstable] +#Server = ftp://ftp.ibiblio.org/pub/linux/distributions/archlinux/unstable +#Server = ftp://ftp.webtrek.com/pub/mirrors/archlinux/unstable +#Server = ftp://ftp.archlinux.org/unstable +#Server = ftp://ftp.mpi-sb.mpg.de/pub/linux/mirror/ftp.ibiblio.org/pub/Linux/distributions/archlinux/unstable +#Server = ftp://ftp.oit.unc.edu/pub/Linux/distributions/archlinux/unstable +#Server = ftp://ftp.tu-chemnitz.de/pub/linux/sunsite.unc-mirror/distributions/archlinux/unstable +#Server = ftp://gd.tuwien.ac.at/opsys/linux/archlinux/unstable +#Server = ftp://saule.mintis.lt/pub/linux/unstable +#Server = ftp://ftp.rez-gif.supelec.fr/pub/Linux/distrib/archlinux/unstable # This is a typical setup for a local package repository. To have pacman # resolve dependencies and install your custom packages with the --sync diff --git a/etc/supfile.arch b/etc/supfile.arch deleted file mode 100644 index 5fe3f4b9..00000000 --- a/etc/supfile.arch +++ /dev/null @@ -1,23 +0,0 @@ -# -# /etc/abs/supfile -# - -# this is the host containing the master ABS files -*default host=cvs.archlinux.org - -*default base=/usr/abs -*default prefix=/usr/abs -*default release=cvs -*default delete -*default use-rel-suffix -*default compress - -# -# Set tag equal to the package tree you wish to follow. CURRENT and -# STABLE are the most commonly used, but you can specify specific -# versions or tag names. Examples are RELEASE_0_2, VEGA, RELEASE_0_3, -# FIREFLY, etc. -# -*default tag=CURRENT - -arch diff --git a/etc/supfile.unofficial b/etc/supfile.unofficial deleted file mode 100644 index 2ed2ef0c..00000000 --- a/etc/supfile.unofficial +++ /dev/null @@ -1,16 +0,0 @@ -# -# /etc/abs/supfile.unofficial -# - -# this is the host containing the unofficial PKGBUILD files -*default host=unofficial.archlinux.org - -*default base=/usr/abs -*default prefix=/usr/abs -*default release=cvs -*default delete -*default use-rel-suffix -*default compress - -*default tag=CURRENT -unofficial diff --git a/scripts/abs b/scripts/abs deleted file mode 100755 index 37e39be8..00000000 --- a/scripts/abs +++ /dev/null @@ -1,51 +0,0 @@ -#!/bin/bash - -myver='2.2' -ABS_ROOT=/usr/abs - -usage() { - echo "abs $myver" - echo "usage: $0" - echo - echo "abs will synchronize PKGBUILD scripts from the CVS repository" - echo "into /usr/abs. You can follow different package trees by editing" - echo "/etc/abs/supfile.arch" - echo - exit 0 -} - -update() { - if [ ! `type -p cvsup` ]; then - echo "abs: cvsup was not found in PATH. Install cvsup" - exit 1 - fi - - if [ ! -d "$ABS_ROOT" ]; then - echo "abs: directory $ABS_ROOT does not exist" - exit 1 - fi - - if [ "`id -u`" != "0" ]; then - echo "abs: you must be root to update your ABS tree" - exit 1 - fi - - for sup in `find /etc/abs -name "supfile.*"`; do - cd $ABS_ROOT && cvsup -L 1 -r 0 -g -c .sup $sup - done -} - -for opt in "$@"; do - case $opt in - -h|--help) - usage - exit 0 ;; - *) - echo "abs: invalid option \"$opt\"" - exit 1 ;; - esac -done - -update - -exit 0 diff --git a/scripts/gensync b/scripts/gensync index 841fae8d..8c6dd320 100755 --- a/scripts/gensync +++ b/scripts/gensync @@ -1,6 +1,6 @@ #!/bin/bash -myver='2.2' +myver='2.3' usage() { echo "gensync $myver" diff --git a/scripts/makepkg b/scripts/makepkg index 7304987d..d8c3938c 100755 --- a/scripts/makepkg +++ b/scripts/makepkg @@ -1,6 +1,6 @@ #!/bin/bash -myver='2.2' +myver='2.3' startdir=`pwd` [ -f /etc/makepkg.conf ] && source /etc/makepkg.conf @@ -13,14 +13,51 @@ msg() { echo $* >&2 } +checkdeps() { + 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 + echo $deplist +} + + if [ "$1" = "--help" -o "$1" = "-h" ]; then shift echo "makepkg version $myver" echo "usage: $0 [options] [build_script]" - echo "options:" - echo " -c, --clean Clean up work files after build" - echo " -i, --install Install package after successful build" - echo " -h, --help This help" + echo "options:" + echo " -c, --clean Clean up work files after build" + echo " -d, --syncdeps Install missing dependencies with pacman" + echo " -b, --builddeps Build missing dependencies from source" + echo " -n, --nodeps Skip all dependency checks" + echo " -i, --install Install package after successful build" + echo " -f, --force Overwrite existing package" + 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." @@ -28,8 +65,13 @@ if [ "$1" = "--help" -o "$1" = "-h" ]; then exit 0 fi +# Options CLEANUP=0 INSTALL=0 +DEP_BIN=0 +DEP_SRC=0 +NODEPS=0 +FORCE=0 BUILDSCRIPT="./PKGBUILD" for arg in $*; do @@ -37,9 +79,21 @@ for arg in $*; do -c|--clean) CLEANUP=1 ;; + -d|--syncdeps) + DEP_BIN=1 + ;; + -b|--builddeps) + DEP_SRC=1 + ;; + -n|--nodeps) + NODEPS=1 + ;; -i|--install) INSTALL=1 ;; + -f|--force) + FORCE=1 + ;; *) BUILDSCRIPT=$arg ;; @@ -79,35 +133,69 @@ if [ `echo $pkgrel | grep '-'` ]; then exit 1 fi -if [ `type -p pacman` ]; then +if [ -f ${pkgname}-${pkgver}-${pkgrel}.pkg.tar.gz -a "$FORCE" = "0" ]; then + 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..." - missdep=`pacman -T ${depends[@]}` - ret=$? - if [ "$ret" != "0" ]; then - if [ "$ret" = "127" ]; then - msg "==> ERROR: Dependency Check Failed:" - msg "" - nl=0 - for dep in $missdep; do - echo -ne "$dep " >&2 - if [ "$nl" = "1" ]; then - nl=0 - echo -ne "\n" >&2 - continue + 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 - nl=1 - done - msg "" - else - msg "==> ERROR: pacman returned a fatal error." - fi - exit 1 + # 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 + makepkg -i -c -b + 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." else msg "==> WARNING: pacman was not found in PATH. skipping dependency checks." fi d=`date` +cd $startdir msg "==> Making package $pkgname ($d)" # extract source @@ -172,6 +260,44 @@ if [ $? -gt 0 ]; then exit 2 fi +# remove info/doc files +cd $startdir +rm -rf pkg/usr/info pkg/usr/share/info +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 +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 +fi + + +# strip binaries +cd $startdir +msg "==> Stripping debugging symbols from libraries..." +find pkg/{,usr,usr/local,opt/*}/lib -type f -exec /usr/bin/strip --strip-debug '{}' ';' 2>&1 +msg "==> Stripping symbols from binaries..." +find pkg/{,usr,usr/local,opt/*}/{bin,sbin} -type f -exec /usr/bin/strip '{}' ';' 2>&1 + # get some package meta info builddate=`date -u "+%a %b %d %k:%M:%S %Y"` if [ "$PACKAGER" != "" ]; then @@ -210,25 +336,6 @@ if [ "$install" != "" ]; then cp $startdir/$install $startdir/pkg/._install fi -# remove info/doc files -cd $startdir -rm -rf pkg/usr/info pkg/usr/share/info -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 -fi - -# strip binaries -cd $startdir -msg "==> Stripping debugging symbols from libraries..." -find pkg/{,usr,usr/local}/lib -type f -exec /usr/bin/strip --strip-debug '{}' ';' 2>&1 -msg "==> Stripping symbols from binaries..." -find pkg/{,usr,usr/local}/{bin,sbin} -type f -exec /usr/bin/strip '{}' ';' 2>&1 - # tar it up msg "==> Compressing package..." cd $startdir/pkg diff --git a/scripts/makeworld b/scripts/makeworld index 7cf04a76..4591c145 100755 --- a/scripts/makeworld +++ b/scripts/makeworld @@ -1,15 +1,19 @@ #!/bin/bash toplevel=`pwd` -version="2.2" +version="2.3" usage() { echo "makeworld version $version" echo "usage: $0 [options] [category] ..." echo "options:" - echo " -c, --clean Clean up work files after build" - echo " -i, --install Install package after successful build" - echo " -h, --help This help" + echo " -c, --clean Clean up work files after build" + echo " -d, --syncdeps Install missing dependencies with pacman" + echo " -b, --builddeps Build missing dependencies from source" + echo " -n, --nodeps Skip all dependency checks" + echo " -i, --install Install package after successful build" + echo " -f, --force Overwrite existing packages" + echo " -h, --help This help" echo echo " where is one or more directory names under the ABS root" echo " eg: makeworld -c /packages base lib editors" @@ -31,6 +35,18 @@ for arg in $*; do -i|--install) MAKEPKG_OPTS="$MAKEPKG_OPTS -i" ;; + -d|--syncdeps) + MAKEPKG_OPTS="$MAKEPKG_OPTS -d" + ;; + -b|--builddeps) + MAKEPKG_OPTS="$MAKEPKG_OPTS -b" + ;; + -n|--nodeps) + MAKEPKG_OPTS="$MAKEPKG_OPTS -n" + ;; + -f|--force) + MAKEPKG_OPTS="$MAKEPKG_OPTS -f" + ;; *) dest=$arg shift diff --git a/scripts/pacsync b/scripts/pacsync deleted file mode 100755 index dd9a9ef9..00000000 --- a/scripts/pacsync +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/sh - -echo -echo "Pacman 2.0+ no longer comes with pacsync. Use 'pacman -S' instead." -echo " (see 'pacman -S --help' or the manpage for syntax)" -echo diff --git a/src/pacman.c b/src/pacman.c index 4d2cbb4b..b6714d22 100644 --- a/src/pacman.c +++ b/src/pacman.c @@ -54,7 +54,7 @@ char* MDFile(char *); */ /* pacman options */ -char* pmo_root = NULL; +char *pmo_root = NULL; unsigned short pmo_op = PM_MAIN; unsigned short pmo_verbose = 0; unsigned short pmo_version = 0; @@ -62,8 +62,10 @@ unsigned short pmo_help = 0; unsigned short pmo_force = 0; unsigned short pmo_nodeps = 0; unsigned short pmo_upgrade = 0; +unsigned short pmo_freshen = 0; unsigned short pmo_nosave = 0; -unsigned short pmo_vertest = 0; +unsigned short pmo_d_vertest = 0; +unsigned short pmo_d_resolve = 0; unsigned short pmo_q_isfile = 0; unsigned short pmo_q_info = 0; unsigned short pmo_q_list = 0; @@ -134,7 +136,7 @@ int main(int argc, char *argv[]) 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(127); + return(32); } /* set signal handlers */ @@ -208,7 +210,7 @@ int pacman_deptest(pacdb_t *db, PMList *targets) PMList *lp, *deps; pkginfo_t *dummy; - if(pmo_vertest) { + if(pmo_d_vertest) { if(targets && targets->data && targets->next && targets->next->data) { int ret = rpmvercmp(targets->data, targets->next->data); printf("%d\n", ret); @@ -231,24 +233,46 @@ int pacman_deptest(pacdb_t *db, PMList *targets) list_free(list); if(deps) { + /* return 126 = deps were missing, but successfully resolved + * return 127 = deps were missing, and failed to resolve; OR + * = deps were missing, but no resolution was attempted; OR + * = unresolvable conflicts were found + */ + int ret = 126; + PMList *synctargs = NULL; for(lp = deps; lp; lp = lp->next) { depmissing_t *miss = (depmissing_t*)lp->data; if(miss->type == CONFLICT) { + /* we can't auto-resolve conflicts */ printf("conflict: %s\n", miss->depend.name); + ret = 127; } else if(miss->type == DEPEND || miss->type == REQUIRED) { - printf("requires: %s", miss->depend.name); - switch(miss->depend.mod) { - case DEP_EQ: printf("=%s", miss->depend.version); break; - case DEP_GE: printf(">=%s", miss->depend.version); break; - case DEP_LE: printf("<=%s", miss->depend.version); break; + if(!pmo_d_resolve) { + printf("requires: %s", miss->depend.name); + switch(miss->depend.mod) { + case DEP_EQ: printf("=%s", miss->depend.version); break; + case DEP_GE: printf(">=%s", miss->depend.version); break; + case DEP_LE: printf("<=%s", miss->depend.version); break; + } + printf("\n"); } - printf("\n"); + synctargs = list_add(synctargs, strdup(miss->depend.name)); } FREE(miss); lp->data = NULL; } FREE(deps); - return(127); + /* attempt to resolve missing dependencies */ + /* TODO: handle version comparators (eg, glibc>=2.2.5) */ + if(ret == 126 && synctargs != NULL) { + if(!pmo_d_resolve || pacman_sync(db, synctargs)) { + /* error (or -D not used) */ + ret = 127; + } + } + list_free(synctargs); + synctargs = NULL; + return(ret); } return(0); } @@ -278,7 +302,7 @@ int pacman_sync(pacdb_t *db, PMList *targets) } oldmask = umask(0000); - if(mkdir("/var/cache/pacman", 0755) && mkdir("/var/cache/pacman/pkg", 0755)) { + if(makepath("/var/cache/pacman/pkg")) { fprintf(stderr, "error: could not create new cache directory: %s\n", strerror(errno)); return(1); } @@ -333,14 +357,18 @@ int pacman_sync(pacdb_t *db, PMList *targets) haystack = strdup(pkg->name); strtoupper(haystack); if(strstr(haystack, targ)) { - printf("%s %s\n", pkg->name, pkg->version); + printf("%s/%s %s\n ", dbs->sync->treename, pkg->name, pkg->version); + indentprint(pkg->desc, 4); + printf("\n"); } else { /* check description */ FREE(haystack); haystack = strdup(pkg->desc); strtoupper(haystack); if(strstr(haystack, targ)) { - printf("%s %s\n", pkg->name, pkg->version); + printf("%s/%s %s\n ", dbs->sync->treename, pkg->name, pkg->version); + indentprint(pkg->desc, 4); + printf("\n"); } } FREE(haystack); @@ -409,7 +437,7 @@ int pacman_sync(pacdb_t *db, PMList *targets) } } } - if(newer) { + if(newer && allgood) { fprintf(stderr, ":: Above packages will be skipped. To manually upgrade use 'pacman -S '\n"); } } else { @@ -439,6 +467,7 @@ int pacman_sync(pacdb_t *db, PMList *targets) } if(!found) { fprintf(stderr, "%s: not found in sync db\n", (char*)i->data); + allgood = 0; continue; } if(local) { @@ -500,7 +529,7 @@ int pacman_sync(pacdb_t *db, PMList *targets) 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); + 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) { @@ -556,7 +585,12 @@ int pacman_sync(pacdb_t *db, PMList *targets) if(pmo_s_downloadonly) { confirm = yesno("\nDo you want to download these packages? [Y/n] "); } else { - confirm = yesno("\nDo you want to install/upgrade these packages? [Y/n] "); + /* don't get any confirmation if we're called from makepkg */ + if(pmo_d_resolve) { + confirm = 1; + } else { + confirm = yesno("\nDo you want to install/upgrade these packages? [Y/n] "); + } } } } @@ -657,7 +691,7 @@ int pacman_sync(pacdb_t *db, PMList *targets) } } if(allgood) { - pacman_upgrade(db, files); + allgood = !pacman_upgrade(db, files); } } @@ -714,11 +748,20 @@ int pacman_add(pacdb_t *db, PMList *targets) fflush(stdout); for(targ = targets; targ; targ = targ->next) { /* Populate the package struct */ - vprint(" %s\n", (char*)targ->data); + vprint("reading %s\n", (char*)targ->data); info = load_pkg((char*)targ->data, 0); if(info == NULL) { return(1); } + if(pmo_freshen) { + /* only upgrade/install this package if it is already installed */ + pkginfo_t *dummy = db_scan(db, info->name, INFRQ_DESC); + if(dummy == NULL) { + freepkg(info); + info = NULL; + continue; + } + } alltargs = list_add(alltargs, info); filenames = list_add(filenames, strdup(targ->data)); } @@ -991,8 +1034,13 @@ int pacman_add(pacdb_t *db, PMList *targets) tar_close(tar); if(errors) { ret = 1; - fprintf(stderr, "error installing %s - skipping db update for this package\n", info->name); - } else { + fprintf(stderr, "errors occurred while %s %s\n", + (pmo_upgrade ? "upgrading" : "installing"), info->name); + +/* XXX: this "else" is disabled so the db_write() ALWAYS occurs. If it doesn't + * packages can get lost during an upgrade. + */ + } /*else*/ { time_t t = time(NULL); /* if this is an upgrade then propagate the old package's requiredby list over to @@ -1001,8 +1049,7 @@ int pacman_add(pacdb_t *db, PMList *targets) list_free(info->requiredby); info->requiredby = NULL; for(lp = oldpkg->requiredby; lp; lp = lp->next) { - char *s = strdup(lp->data); - info->requiredby = list_add(info->requiredby, s); + info->requiredby = list_add(info->requiredby, strdup(lp->data)); } } @@ -1230,6 +1277,18 @@ int pacman_remove(pacdb_t *db, PMList *targets) } } + /* run ldconfig if it exists */ + snprintf(line, PATH_MAX, "%setc/ld.so.conf", pmo_root); + if(!stat(line, &buf)) { + snprintf(line, PATH_MAX, "%ssbin/ldconfig", pmo_root); + if(!stat(line, &buf)) { + char cmd[PATH_MAX]; + snprintf(cmd, PATH_MAX, "%s -r %s", line, pmo_root); + vprint("running \"%s\"\n", cmd); + system(cmd); + } + } + return(0); } @@ -1477,7 +1536,8 @@ int resolvedeps(pacdb_t *local, PMList *databases, syncpkg_t *syncpkg, PMList *l continue; } if(miss->type == CONFLICT) { - fprintf(stderr, "error: %s conflicts with %s\n", miss->target, miss->depend.name); + fprintf(stderr, "error: cannot resolve dependencies for \"%s\":\n", miss->target); + fprintf(stderr, " %s conflicts with %s\n", miss->target, miss->depend.name); return(1); } else if(miss->type == DEPEND) { /*printf("resolving %s\n", sync->pkg->name); fflush(stdout);*/ @@ -1639,7 +1699,7 @@ PMList* checkdeps(pacdb_t *db, unsigned short op, PMList *targets) miss->depend.mod = DEP_ANY; miss->depend.version[0] = '\0'; strncpy(miss->target, tp->name, 256); - strncpy(miss->depend.name, (char*)j->data, 256); + strncpy(miss->depend.name, info->name, 256); baddeps = list_add(baddeps, miss); } } diff --git a/src/pacman.h b/src/pacman.h index c9794737..c9b06219 100644 --- a/src/pacman.h +++ b/src/pacman.h @@ -22,7 +22,7 @@ #define _PAC_PACMAN_H #ifndef PACVER -#define PACVER "2.2" +#define PACVER "2.3" #endif #ifndef PKGDIR @@ -37,8 +37,8 @@ #define PM_MAIN 1 #define PM_ADD 2 #define PM_REMOVE 3 -#define PM_QUERY 4 -#define PM_UPGRADE 5 +#define PM_UPGRADE 4 +#define PM_QUERY 5 #define PM_SYNC 6 #define PM_DEPTEST 7 diff --git a/src/util.c b/src/util.c index 6d4c1bc7..cba4a050 100644 --- a/src/util.c +++ b/src/util.c @@ -45,8 +45,10 @@ 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_vertest; +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; @@ -139,10 +141,12 @@ int parseargs(int op, int argc, char **argv) {"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'}, @@ -162,7 +166,7 @@ int parseargs(int op, int argc, char **argv) {0, 0, 0, 0} }; - while((opt = getopt_long(argc, argv, "ARUQSTYr:vhscVfnoldpiuwy", opts, &option_index))) { + while((opt = getopt_long(argc, argv, "ARUFQSTDYr:vhscVfnoldpiuwy", opts, &option_index))) { if(opt < 0) { break; } @@ -171,10 +175,12 @@ int parseargs(int op, int argc, char **argv) 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_vertest = 1; 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; @@ -483,6 +489,7 @@ void usage(int op, char *myname) printf(" %s {-A --add} [options] \n", myname); printf(" %s {-R --remove} [options] \n", myname); printf(" %s {-U --upgrade} [options] \n", myname); + printf(" %s {-F --freshen} [options] \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); @@ -490,26 +497,30 @@ void usage(int op, char *myname) if(op == PM_ADD) { printf("usage: %s {-A --add} [options] \n", myname); printf("options:\n"); - printf(" -f, --force force install, overwrite conflicting files\n"); - printf(" -d, --nodeps skip dependency checks\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] \n", myname); printf("options:\n"); - printf(" -d, --nodeps skip dependency checks\n"); - printf(" -n, --nosave remove configuration files as well\n"); + printf(" -d, --nodeps skip dependency checks\n"); + printf(" -n, --nosave remove configuration files as well\n"); } else if(op == PM_UPGRADE) { - printf("usage: %s {-U --upgrade} [options] \n", myname); + if(pmo_freshen) { + printf("usage: %s {-F --freshen} [options] \n", myname); + } else { + printf("usage: %s {-U --upgrade} [options] \n", myname); + } printf("options:\n"); - printf(" -f, --force force install, overwrite conflicting files\n"); - printf(" -d, --nodeps skip dependency checks\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 query the package that owns \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"); + printf(" -o, --owns query the package that owns \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"); @@ -521,8 +532,8 @@ void usage(int op, char *myname) 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 set an alternate installation root\n"); + printf(" -v, --verbose be verbose\n"); + printf(" -r, --root set an alternate installation root\n"); } } @@ -570,6 +581,50 @@ int yesno(char *fmt, ...) } return(0); } + +/* output a string, but wrap words properly with a specified indentation + */ +void indentprint(char *str, int indent) +{ + char *p = str; + char *cenv = NULL; + int cols = 80; + int cidx = indent; + + cenv = getenv("COLUMNS"); + if(cenv) { + cols = atoi(cenv); + } + + while(*p) { + if(*p == ' ') { + char *next = NULL; + int len; + p++; + if(p == NULL || *p == ' ') continue; + next = strchr(p, ' '); + if(next == NULL) { + next = p + strlen(p); + } + len = next - p; + if(len > (cols-cidx-1)) { + /* newline */ + int i; + printf("\n"); + for(i = 0; i < indent; i++) { + printf(" "); + } + cidx = indent; + } else { + printf(" "); + cidx++; + } + } + printf("%c", *p); + p++; + cidx++; + } +} /* Test for existence of a string in a PMList */ diff --git a/src/util.h b/src/util.h index 132d7c06..222c00fa 100644 --- a/src/util.h +++ b/src/util.h @@ -38,6 +38,7 @@ 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); diff --git a/src/vercmp.c b/src/vercmp.c new file mode 100644 index 00000000..850ebea6 --- /dev/null +++ b/src/vercmp.c @@ -0,0 +1,25 @@ +#include +#include + +int rpmvercmp(const char *a, const char *b); + +int main(int argc, char *argv[]) +{ + char s1[255] = ""; + char s2[255] = ""; + int ret; + + if(argc > 1) { + strncpy(s1, argv[1], 255); + } + if(argc > 2) { + strncpy(s2, argv[2], 255); + } else { + printf("0\n"); + return(0); + } + + ret = rpmvercmp(s1, s2); + printf("%d\n", ret); + return(ret); +} -- cgit v1.2.3-24-g4f1b