summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJudd Vinet <judd@archlinux.org>2002-09-16 07:22:13 +0200
committerJudd Vinet <judd@archlinux.org>2002-09-16 07:22:13 +0200
commit6a654187b68d37211dc8af301e611ec4a7f132c4 (patch)
treec215ad278a485fac7c0361fa9d5fcae8b101929b
parent62a783a6bd7649ccd162e32278098080bf450c7b (diff)
downloadpacman-6a654187b68d37211dc8af301e611ec4a7f132c4.tar.gz
pacman-6a654187b68d37211dc8af301e611ec4a7f132c4.tar.xz
Imported from pacman-2.1.tar.gz
-rw-r--r--Makefile.in6
-rw-r--r--TODO17
-rw-r--r--doc/pacman.8.in66
-rw-r--r--etc/pacman.conf96
-rw-r--r--etc/supfile.arch (renamed from etc/supfile)4
-rw-r--r--etc/supfile.unofficial16
-rwxr-xr-xscripts/abs13
-rwxr-xr-xscripts/gensync104
-rwxr-xr-xscripts/makepkg130
-rwxr-xr-xscripts/makeworld57
-rwxr-xr-xscripts/pacsync2
-rw-r--r--src/db.c1
-rw-r--r--src/list.c12
-rw-r--r--src/list.h1
-rw-r--r--src/package.c1
-rw-r--r--src/pacman.c462
-rw-r--r--src/pacman.h4
-rw-r--r--src/pacsync.c230
-rw-r--r--src/pacsync.h25
-rw-r--r--src/util.c145
20 files changed, 959 insertions, 433 deletions
diff --git a/Makefile.in b/Makefile.in
index e2c4798b..07e5d802 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.0
+PACVER = 2.1
LIBTAR_VERSION = 1.2.5
TOPDIR = @srcdir@
@@ -105,11 +105,13 @@ install: pacman convertdb man
$(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 $(DESTDIR)/etc/abs/supfile
+ $(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
diff --git a/TODO b/TODO
index 5dde8fdb..2e4c64e6 100644
--- a/TODO
+++ b/TODO
@@ -1,7 +1,14 @@
+- have "group" designations
+- use 'set -e' in makepkg?
+- if a package fails, ask before aborting the full operation
+- 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?
-- use a provides tag (instead of an OR operator in depends)
- instead of 'conflicts' use a ! operator in depends
- add a --pretend option
- add a consistency/sanity check operation
@@ -11,12 +18,10 @@
- use package caches more for performance
+ add an "ignore package" option in either pacman.conf or in each package
record. this will prevent it from being upgraded from the sync set
+- 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?)
-- add an OR operator to dependencies or allow a sibling tag (ie, mawk, gawk)
- run ldd on every executable in a newly built package to find required so's
-- add a freshen operation
-- allow multiple ftp servers to be defined and fallback to backups on failure
- use a files.cache gdbm (or whatever) for --owns and db_find_conflicts
-- things like 'groupadd' and 'useradd' in the install scriptlets will affect
- the real root, not the one specified with -r
+
diff --git a/doc/pacman.8.in b/doc/pacman.8.in
index dd3da750..d8bb26b7 100644
--- a/doc/pacman.8.in
+++ b/doc/pacman.8.in
@@ -1,4 +1,4 @@
-.TH pacman 8 "July 18, 2002" "pacman #VERSION#" ""
+.TH pacman 8 "August 18, 2002" "pacman #VERSION#" ""
.SH NAME
pacman \- package manager utility
.SH SYNOPSIS
@@ -149,21 +149,55 @@ All three files are different. So we install the new file, but back up the
old one to a .pacsave extension. This way the user can move the old configuration
file back into place if he wishes.
.SH CONFIGURATION
-pacman will attempt to read \fI/etc/pacman.conf\fP each time it is invoked. Currently
-the only options in it are for the --sync operation, but more may be added later.
-.TP
-.B "Sync_Tree_Name"
-Sets the name of the package set you wish to follow. The common choices are \fIcurrent\fP
-and \fIstable\fP. You could also specify a specific package version, eg, 0.3.
-.TP
-.B "Sync_Server"
-This is the hostname of the ftp server that will be used for downloading lists and
-packages. eg, \fIftp.ibiblio.org\fP.
-.TP
-.B "Sync_Tree_Path"
-This is the full path name (on the ftp server) to the package tree you are following.
-So if you are following \fIcurrent\fP, on \fIftp.ibiblio.org\fP, you would use
-\fI/pub/linux/distributions/archlinux/current\fP.
+pacman will attempt to read \fI/etc/pacman.conf\fP each time it is invoked. This
+configuration file is divided into sections or \fIrepositories\fP. Each section
+defines a package repository that pacman can use when searching for packages in
+--sync mode. The exception to this is the \fIoptions\fP section, which defines
+global options.
+.TP
+.SH Example:
+.RS
+.nf
+[options]
+NoUpgrade = etc/passed etc/group etc/shadow
+NoUpgrade = etc/fstab
+
+[current]
+Server = ftp://ftp.server.org/linux/archlinux/current
+Server = ftp://ftp.mirror.com/arch/current
+
+[custom]
+Server = local:///home/pkgs
+
+.fi
+.RE
+All files listed with a \fINoUpgrade\fP directive will never be touched during a package
+install/upgrade. This directive is only valid in the options section.
+
+Each repository section defines a section name and at least one location where the packages
+can be found. The section name is defined by the string within square brackets (eg, the two
+above are 'current' and 'custom'). Locations are defined with the \fIServer\fP directive and
+follow a URL naming structure. Currently only ftp is supported for remote servers. If you
+want to use a local directory, you can specify the full path with a 'local://' prefix, as
+shown above.
+.SH USING YOUR OWN REPOSITORY
+Let's say you have a bunch of custom packages in \fI/home/pkgs\fP and their respective PKGBUILD
+files are all in \fI/usr/abs/local\fP. All you need to do is generate a compressed package database
+in the \fI/home/pkgs\fP directory so pacman can find it when run with --refresh.
+
+.RS
+.nf
+# gensync /usr/abs/local /home/pkgs/custom.db.tar.gz
+.fi
+.RE
+
+The above command will read all PKGBUILD files in /usr/abs/local and generate a compressed
+database called /home/pkgs/custom.db.tar.gz. Note that the database must be of the form
+\fI{treename}.db.tar.gz\fP, where {treename} is the name of the section defined in the
+configuration file.
+That's it! Now configure your \fIcustom\fP section in the configuration file as shown in the
+config example above. Pacman will now use your package repository. If you add new packages to
+the repository, remember to re-generate the database and use pacman's --refresh option.
.SH SEE ALSO
\fBmakepkg\fP is the package-building tool that comes with pacman.
.SH AUTHOR
diff --git a/etc/pacman.conf b/etc/pacman.conf
index 8ffb78b5..c0b833b6 100644
--- a/etc/pacman.conf
+++ b/etc/pacman.conf
@@ -2,34 +2,78 @@
# /etc/pacman.conf
#
-# name of the tree you want to follow (eg: stable, current, 0.2, 0.3, ...)
-Sync_Tree_Name = current
+# Currently the only option directive is NoUpgrade. Use this with a
+# space-delimited list of files that should never be touched by pacman
+# during an install/upgrade. (note: do not include the leading slash)
+[options]
+NoUpgrade = etc/passwd etc/group etc/shadow
+NoUpgrade = etc/fstab
-# ftp server
-Sync_Server = ftp.ibiblio.org
+[current]
+Server = ftp://ftp.ibiblio.org/pub/linux/distributions/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://gd.tuwien.ac.at/opsys/linux/archlinux/current
+Server = ftp://ftp2.archlinux.org/current
+Server = ftp://ftp3.archlinux.org/current
+Server = ftp://ftp.archlinux.org/current
-# full path to sync tree
-Sync_Tree_Path = /pub/linux/distributions/archlinux/current
-
-###
-### MIRRORS
-#########################
-
-# Sync_Server = ftp.mpi-sb.mpg.de
-# Sync_Tree_Path = /pub/linux/mirror/ftp.ibiblio.org/pub/Linux/distributions/archlinux/current
-
-# Sync_Server = ftp2.archlinux.org
-# Sync_Tree_Path = /current
-
-# Sync_Server = ftp.oit.unc.edu
-# Sync_Tree_Path = /pub/Linux/distributions/archlinux/current
-
-# Sync_Server = ftp.tu-chemnitz.de
-# Sync_Tree_Path = /pub/linux/sunsite.unc-mirror/distributions/archlinux/current
+# Uncomment this block to access the 'unofficial' package set
+#
+#[unofficial]
+#Server = ftp://ftp.ibiblio.org/pub/linux/distributions/archlinux/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://gd.tuwien.ac.at/opsys/linux/archlinux/unofficial
+#Server = ftp://ftp2.archlinux.org/unofficial
+#Server = ftp://ftp3.archlinux.org/unofficial
+#Server = ftp://ftp.archlinux.org/unofficial
-# Sync_Server = ftp.archlinux.org
-# Sync_Tree_Path = /current
+# If you use the 'stable' tree, you should disable the 'current'
+# tree to avoid conflicts
+#
+#[stable]
+#Server = ftp://ftp.ibiblio.org/pub/linux/distributions/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://ftp.oit.unc.edu/pub/Linux/distributions/archlinux/stable
+#Server = ftp://ftp2.archlinux.org/stable
+#Server = ftp://ftp3.archlinux.org/stable
-# Sync_Server = ftp.oit.unc.edu
-# Sync_Tree_Path = /pub/Linux/distributions/archlinux/current
+# This is a typical setup for a local package repository. To have pacman
+# resolve dependencies and install your custom packages with the --sync
+# operation, you must generate a sync db from your custom PKGBUILDs and
+# place it in the directory specified by the Server directive.
+#
+# # gensync /usr/abs/local /home/custompkgs/custom.db.tar.gz
+#
+# The sync database must be of the form {treename}.db.gz, where treename
+# is the name of the package tree (in this case, 'custom').
+#
+# Then you can activate this custom repository by uncommenting the last
+# two lines and using pacman as usual:
+#
+# # pacman -S --refresh
+# :: Synchronizing package databases...
+# current.db.tar.gz [#################################] 100% | 20K
+# custom.db.tar.gz [/home/custompkgs/ ] 100% | LOCAL
+#
+# # pacman -S my_custom_pkg
+#
+# Targets: my_custom_pkg-0.12-1
+#
+# Do you want to install/upgrade these packages? [Y/n]
+#
+# :: Retrieving packages from custom...
+# my_custom_pkg-0.12-1.pkg [/home/custompkgs/ ] 100% | LOCAL
+#
+# checking for conflicts... done.
+# installing my_custom_pkg... done.
+#
+#[custom]
+#Server = local:///home/custompkgs
diff --git a/etc/supfile b/etc/supfile.arch
index 274b0e46..5fe3f4b9 100644
--- a/etc/supfile
+++ b/etc/supfile.arch
@@ -3,7 +3,7 @@
#
# this is the host containing the master ABS files
-*default host=archlinux.org
+*default host=cvs.archlinux.org
*default base=/usr/abs
*default prefix=/usr/abs
@@ -20,4 +20,4 @@
#
*default tag=CURRENT
-abs
+arch
diff --git a/etc/supfile.unofficial b/etc/supfile.unofficial
new file mode 100644
index 00000000..2ed2ef0c
--- /dev/null
+++ b/etc/supfile.unofficial
@@ -0,0 +1,16 @@
+#
+# /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
index a21bcb68..10e9b9c4 100755
--- a/scripts/abs
+++ b/scripts/abs
@@ -1,6 +1,6 @@
#!/bin/bash
-myver='2.0'
+myver='2.1'
ABS_ROOT=/usr/abs
usage() {
@@ -9,7 +9,7 @@ usage() {
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"
+ echo "/etc/abs/supfile.arch"
echo
exit 0
}
@@ -25,17 +25,14 @@ update() {
exit 1
fi
- if [ ! -r /etc/abs/supfile ]; then
- echo "abs: missing config file /etc/abs/supfile"
- exit 1
- fi
-
if [ "`id -u`" != "0" ]; then
echo "abs: you must be root to update your ABS tree"
exit 1
fi
- cd $ABS_ROOT && cvsup -L 1 -r 0 -g -c .sup /etc/abs/supfile
+ 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
diff --git a/scripts/gensync b/scripts/gensync
new file mode 100755
index 00000000..4b0f882d
--- /dev/null
+++ b/scripts/gensync
@@ -0,0 +1,104 @@
+#!/bin/bash
+
+myver='2.1'
+
+usage() {
+ echo "gensync $myver"
+ echo "usage: $0 <root> <destfile>"
+ echo
+ echo "gensync will generate a sync database by reading all PKGBUILD files"
+ echo "from <root>. gensync builds the database in /tmp/.gensync and then"
+ echo "compresses it to <destfile>."
+ echo
+ echo "note: The <destfile> name is important. It must be of the form"
+ echo " {treename}.db.tar.gz where {treename} is the name of the custom"
+ echo " package repository you configured in /etc/pacman.conf. The"
+ echo " generated database must reside in the same directory as your"
+ echo " custom packages (also configured in /etc/pacman.conf)"
+ echo
+ echo "example: gensync /usr/abs/local /home/mypkgs/custom.db.tar.gz"
+ echo
+ echo
+ exit 0
+}
+
+db_write_entry()
+{
+ unset pkgname pkgver pkgrel
+ unset depends conflicts
+ source $1 || return 1
+ cd /tmp/.gensync
+ mkdir $pkgname-$pkgver-$pkgrel
+ cd $pkgname-$pkgver-$pkgrel
+ # desc
+ echo "%NAME%" >desc
+ echo "$pkgname" >>desc
+ echo "" >>desc
+ echo "%VERSION%" >>desc
+ echo "$pkgver-$pkgrel" >>desc
+ echo "" >>desc
+ echo "%DESC%" >>desc
+ echo "$pkgdesc" >>desc
+ echo "" >>desc
+ # depends
+ echo "%DEPENDS%" >depends
+ for depend in "${depends[@]}"; do
+ echo "$depend" >>depends
+ done
+ echo "" >>depends
+ echo "%CONFLICTS%" >>depends
+ for conflict in "${conflicts[@]}"; do
+ echo "$conflict" >>depends
+ done
+ echo "" >>depends
+}
+
+if [ $# -lt 2 ]; then
+ usage
+ exit 0
+fi
+
+if [ "$1" = "-h" -o "$1" = "--help" ]; then
+ usage
+ exit 0
+fi
+
+d=`dirname $1`
+rootdir=`cd $d && pwd`
+rootdir="$rootdir/`basename $1`"
+d=`dirname $2`
+destfile=`cd $d && pwd`
+destfile="$destfile/`basename $2`"
+
+rm -rf /tmp/.gensync || exit 1
+mkdir -p /tmp/.gensync || exit 1
+
+if [ ! -d $rootdir ]; then
+ echo "gensync: invalid root dir: $rootdir" >&2
+ rm -rf /tmp/.gensync
+ exit 1
+fi
+
+echo "gensync: building database entries..." >&2
+#for category in `find $rootdir/* -type d -maxdepth 0`; do
+for file in `find $rootdir/* -name PKGBUILD`; do
+ db_write_entry $file
+ if [ $? -gt 0 ]; then
+ echo "gensync: error writing entry for $file" >&2
+ rm -rf /tmp/.gensync
+ exit 1
+ fi
+done
+
+echo "gensync: compressing to $destfile..." >&2
+cd /tmp/.gensync
+tar c * | gzip -9 >$destfile
+if [ $? -gt 0 ]; then
+ echo "gensync: error writing to $destfile" >&2
+ rm -rf /tmp/.gensync
+ exit 1
+fi
+
+rm -rf /tmp/.gensync
+
+exit 0
diff --git a/scripts/makepkg b/scripts/makepkg
index 2774084f..35e7dac9 100755
--- a/scripts/makepkg
+++ b/scripts/makepkg
@@ -1,6 +1,6 @@
#!/bin/bash
-myver='2.0'
+myver='2.1'
startdir=`pwd`
[ -f /etc/makepkg.conf ] && source /etc/makepkg.conf
@@ -30,21 +30,26 @@ fi
CLEANUP=0
INSTALL=0
+BUILDSCRIPT="./PKGBUILD"
-if [ "$1" = "-c" -o "$1" = "--clean" ]; then
- shift
- CLEANUP=1
-fi
-if [ "$1" = "-i" -o "$1" = "--install" ]; then
- shift
- INSTALL=1
-fi
+for arg in $*; do
+ case $arg in
+ -c|--clean)
+ CLEANUP=1
+ ;;
+ -i|--install)
+ INSTALL=1
+ ;;
+ *)
+ BUILDSCRIPT=$arg
+ ;;
+ esac
+done
unset pkgname pkgver pkgrel pkgdesc
unset depends conflicts backup source install build
umask 0022
-
# check for a download utility
if [ -x /usr/bin/wget ]; then
ftpagent="/usr/bin/wget --passive-ftp --tries=3 --waitretry=3"
@@ -57,11 +62,6 @@ else
exit 1
fi
-BUILDSCRIPT="./PKGBUILD"
-if [ "$1" != "" ]; then
- BUILDSCRIPT=$1
-fi
-
if [ ! -f $BUILDSCRIPT ]; then
msg "==> ERROR: $BUILDSCRIPT does not exist."
exit 1
@@ -71,40 +71,40 @@ 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 [ `type -p pacman` ]; 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
- fi
- nl=1
- done
- msg ""
- else
- msg "==> ERROR: pacman returned a fatal error."
- fi
- exit 1
- fi
+ 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
+ fi
+ nl=1
+ done
+ msg ""
+ else
+ msg "==> ERROR: pacman returned a fatal error."
+ fi
+ exit 1
+ fi
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`
@@ -143,21 +143,21 @@ for netfile in ${source[@]}; do
cmd="tar --use-compress-program=gzip -xf $file" ;;
*.tar.bz2)
cmd="tar --use-compress-program=bzip2 -xf $file" ;;
- *.tar)
- cmd="tar -xf $file" ;;
+ *.tar)
+ cmd="tar -xf $file" ;;
*.zip)
cmd="unzip -qq $file" ;;
- *)
- cmd="cp ../$file ." ;;
- esac
- msg "==> $cmd"
- $cmd
+ *.gz)
+ cmd="gunzip $file" ;;
+ esac
+ msg "==> $cmd"
+ $cmd
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
@@ -172,9 +172,9 @@ fi
# 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}'`
@@ -203,8 +203,8 @@ 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
# remove info/doc files
@@ -214,9 +214,9 @@ 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
# strip binaries
@@ -230,23 +230,23 @@ find pkg/{,usr,usr/local}/{bin,sbin} -type f -exec /usr/bin/strip '{}' ';' 2>&1
msg "==> Compressing package..."
cd $startdir/pkg
if [ -f $startdir/pkg/._install ]; then
- tar czvf $startdir/$pkgname-$pkgver-$pkgrel.pkg.tar.gz .PKGINFO ._install * >../filelist
+ tar czvf $startdir/$pkgname-$pkgver-$pkgrel.pkg.tar.gz .PKGINFO ._install * >../filelist
else
- tar czvf $startdir/$pkgname-$pkgver-$pkgrel.pkg.tar.gz .PKGINFO * >../filelist
+ tar czvf $startdir/$pkgname-$pkgver-$pkgrel.pkg.tar.gz .PKGINFO * >../filelist
fi
cd $startdir
if [ "$CLEANUP" = "1" ]; then
- msg "==> Cleaning up"
- rm -rf src pkg
+ msg "==> Cleaning up"
+ rm -rf src pkg
fi
d=`date`
msg "==> Finished making $pkgname ($d)"
if [ "$INSTALL" = "1" ]; then
- msg "==> Running pacman --upgrade"
- pacman --upgrade $pkgname-$pkgver-$pkgrel.pkg.tar.gz
+ msg "==> Running pacman --upgrade"
+ pacman --upgrade $pkgname-$pkgver-$pkgrel.pkg.tar.gz
fi
exit 0
diff --git a/scripts/makeworld b/scripts/makeworld
index 8b3ec177..448dbc49 100755
--- a/scripts/makeworld
+++ b/scripts/makeworld
@@ -1,35 +1,52 @@
#!/bin/bash
toplevel=`pwd`
-version="2.0"
+version="2.1"
-if [ $# -lt 2 -o "$1" = "--help" -o "$1" = "-h" ]; then
- echo "makeworld version $version"
+usage() {
+ echo "makeworld version $version"
echo "usage: $0 [options] <destdir> <category> [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
- echo " where <category> is one or more of base, opt, contrib"
- echo " eg: makeworld /packages base opt"
+ 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
+ echo " where <category> is one or more directory names under the ABS root"
+ echo " eg: makeworld -c /packages base lib editors"
echo
echo " this should be run from the toplevel directory of ABS (usually /usr/abs)"
+}
+
+if [ $# -lt 2 -o "$1" = "--help" -o "$1" = "-h" ]; then
+ usage
exit 1
fi
MAKEPKG_OPTS=
-if [ "$1" = "-c" -o "$1" = "--clean" ]; then
- shift
- MAKEPKG_OPTS="$MAKEPKG_OPTS -c"
-fi
-if [ "$1" = "-i" -o "$1" = "--install" ]; then
- shift
- MAKEPKG_OPTS="$MAKEPKG_OPTS -i"
-fi
+for arg in $*; do
+ case $arg in
+ -c|--clean)
+ MAKEPKG_OPTS="$MAKEPKG_OPTS -c"
+ ;;
+ -i|--install)
+ MAKEPKG_OPTS="$MAKEPKG_OPTS -i"
+ ;;
+ *)
+ dest=$arg
+ shift
+ break
+ ;;
+ esac
+ shift
+ if [ "$dest" != "" ]; then
+ break;
+ fi
+done
-dest=$1
-shift
+if [ "$dest" = "" ]; then
+ usage
+ exit 1
+fi
sd=`date +"[%b %d %H:%M]"`
diff --git a/scripts/pacsync b/scripts/pacsync
index 7537f284..dd9a9ef9 100755
--- a/scripts/pacsync
+++ b/scripts/pacsync
@@ -1,6 +1,6 @@
#!/bin/sh
echo
-echo "Pacman 2.0 no longer comes with pacsync. Use 'pacman -S' instead."
+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/db.c b/src/db.c
index f747be5b..b2489bb1 100644
--- a/src/db.c
+++ b/src/db.c
@@ -31,6 +31,7 @@
#include "package.h"
#include "db.h"
#include "util.h"
+#include "pacsync.h"
#include "pacman.h"
extern PMList *pm_packages;
diff --git a/src/list.c b/src/list.c
index 2a33b6e3..717aab2b 100644
--- a/src/list.c
+++ b/src/list.c
@@ -93,6 +93,18 @@ int list_count(PMList *list)
return(i);
}
+int list_isin(PMList *haystack, void *needle)
+{
+ PMList *lp;
+
+ for(lp = haystack; lp; lp = lp->next) {
+ if(lp->data == needle) {
+ return(1);
+ }
+ }
+ return(0);
+}
+
/* List one is extended and returned
* List two is freed (but not its data)
*/
diff --git a/src/list.h b/src/list.h
index 9749d934..68ff5651 100644
--- a/src/list.h
+++ b/src/list.h
@@ -12,6 +12,7 @@ PMList* list_new();
void list_free(PMList* list);
PMList* list_add(PMList* list, void* data);
int list_count(PMList* list);
+int list_isin(PMList *haystack, void *needle);
PMList* list_merge(PMList *one, PMList *two);
PMList* list_last(PMList* list);
diff --git a/src/package.c b/src/package.c
index 69461f67..95913b14 100644
--- a/src/package.c
+++ b/src/package.c
@@ -30,6 +30,7 @@
#include "package.h"
#include "db.h"
#include "util.h"
+#include "pacsync.h"
#include "pacman.h"
extern tartype_t gztype;
diff --git a/src/pacman.c b/src/pacman.c
index 7c70cacd..053c5081 100644
--- a/src/pacman.c
+++ b/src/pacman.c
@@ -72,25 +72,24 @@ unsigned short pmo_s_upgrade = 0;
unsigned short pmo_s_sync = 0;
unsigned short pmo_s_search = 0;
unsigned short pmo_s_clean = 0;
+PMList *pmo_noupgrade = NULL;
-/* configuration options */
-char pmc_syncserver[512] = "";
-char pmc_syncpath[512] = "";
-char pmc_syncname[512] = "";
-
-char *lckfile = "/tmp/pacman.lck";
+/* list of sync_t structs for sync locations */
+PMList *pmc_syncs = NULL;
/* list of installed packages */
PMList *pm_packages = NULL;
-
/* list of targets specified on command line */
-PMList *pm_targets = NULL;
+PMList *pm_targets = NULL;
+
+char *lckfile = "/tmp/pacman.lck";
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;
@@ -141,6 +140,12 @@ int main(int argc, char *argv[])
signal(SIGINT, cleanup);
signal(SIGTERM, cleanup);
+ /* parse the system-wide config file */
+ snprintf(path, PATH_MAX, "/%s", PACCONF);
+ if(parseconfig(path)) {
+ cleanup(1);
+ }
+
/* check for db existence */
/* add a trailing '/' if there isn't one */
if(pmo_root[strlen(pmo_root)-1] != '/') {
@@ -249,37 +254,18 @@ int pacman_deptest(pacdb_t *db, PMList *targets)
int pacman_sync(pacdb_t *db, PMList *targets)
{
- char url[1024];
- char *dbpath = NULL;
+ char dbpath[PATH_MAX];
int allgood = 1, confirm = 0;
- pacdb_t *db_sync = NULL;
- PMList *pkgcache = NULL;
- PMList *i, *j;
+ int cols;
+ PMList *i, *j, *k;
PMList *final = NULL;
PMList *trail = NULL;
- PMList *deps = NULL;
- int cols;
+ PMList *databases = NULL;
- /* parse the system-wide config file */
- snprintf(url, 511, "/%s", PACCONF);
- if(parseconfig(url)) {
+ if(!list_count(pmc_syncs)) {
+ fprintf(stderr, "error: no usable package repositories configured.\n");
return(1);
}
- if(!strlen(pmc_syncserver)) {
- fprintf(stderr, "error: no Sync_Server specified in %s\n", url);
- return(1);
- }
- if(!strlen(pmc_syncname)) {
- fprintf(stderr, "error: no Sync_Tree_Name specified in %s\n", url);
- return(1);
- }
- if(!strlen(pmc_syncpath)) {
- fprintf(stderr, "error: no Sync_Tree_Path specified in %s\n", url);
- return(1);
- }
- if(pmc_syncpath[0] != '/') {
- sprintf(pmc_syncpath, "/%s", pmc_syncpath);
- }
if(pmo_s_clean) {
mode_t oldmask;
@@ -303,54 +289,61 @@ int pacman_sync(pacdb_t *db, PMList *targets)
if(pmo_s_sync && !pmo_s_search) {
/* grab a fresh package list */
- printf(":: Synchronizing remote package tree... \n");
+ printf(":: Synchronizing package databases... \n");
sync_synctree();
- printf("\n");
- }
-
- /* open the sync db */
- MALLOC(dbpath, PATH_MAX);
- snprintf(dbpath, PATH_MAX-1, "%s%s", pmo_root, PKGDIR);
- db_sync = db_open(dbpath, pmc_syncname);
- if(db_sync == NULL) {
- fprintf(stderr, "error: could not open the sync database.\n");
- fprintf(stderr, " have you used --refresh yet?\n");
- return(1);
}
- /* cache packages */
- pkgcache = db_loadpkgs(db_sync, pkgcache);
- if(db_sync == NULL) {
- fprintf(stderr, "error: could not open sync database (%s/%s)\n", dbpath, pmc_syncname);
- return(1);
+ /* open the database(s) */
+ for(i = pmc_syncs; i; i = i->next) {
+ pacdb_t *db_sync = NULL;
+ 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);
+ if(db_sync == NULL) {
+ fprintf(stderr, "error: could not open sync database: %s\n", sync->treename);
+ fprintf(stderr, " have you used --refresh yet?\n");
+ return(1);
+ }
+ MALLOC(dbs, sizeof(dbsync_t));
+ dbs->sync = sync;
+ dbs->db = db_sync;
+ /* cache packages */
+ dbs->pkgcache = NULL;
+ dbs->pkgcache = db_loadpkgs(db_sync, dbs->pkgcache);
+ databases = list_add(databases, dbs);
}
final = list_new();
trail = list_new();
if(pmo_s_search) {
- /* search sync db */
+ /* search sync databases */
for(i = targets; i; i = i->next) {
char *targ = strdup(i->data);
strtoupper(targ);
- for(j = pkgcache; j; j = j->next) {
- pkginfo_t *pkg = (pkginfo_t*)j->data;
- char *haystack;
- /* check name */
- haystack = strdup(pkg->name);
- strtoupper(haystack);
- if(strstr(haystack, targ)) {
- printf("%s %s\n", pkg->name, pkg->version);
- } else {
- /* check description */
- FREE(haystack);
- haystack = strdup(pkg->desc);
+ for(j = databases; j; j = j->next) {
+ dbsync_t *dbs = (dbsync_t*)j->data;
+ for(k = dbs->pkgcache; k; k = k->next) {
+ pkginfo_t *pkg = (pkginfo_t*)k->data;
+ char *haystack;
+ /* check name */
+ haystack = strdup(pkg->name);
strtoupper(haystack);
if(strstr(haystack, targ)) {
printf("%s %s\n", pkg->name, pkg->version);
+ } else {
+ /* check description */
+ FREE(haystack);
+ haystack = strdup(pkg->desc);
+ strtoupper(haystack);
+ if(strstr(haystack, targ)) {
+ printf("%s %s\n", pkg->name, pkg->version);
+ }
}
+ FREE(haystack);
}
- FREE(haystack);
}
FREE(targ);
}
@@ -359,18 +352,18 @@ int pacman_sync(pacdb_t *db, PMList *targets)
for(i = pm_packages; i && allgood; i = i->next) {
int cmp, found = 0;
pkginfo_t *local = (pkginfo_t*)i->data;
- pkginfo_t *sync = NULL;
-
- for(j = pkgcache; !found && j; j = j->next) {
- sync = (pkginfo_t*)j->data;
- if(local == NULL || local->name == NULL) {
- vprint("local is NULL!\n");
- }
- if(sync == NULL || sync->name == NULL) {
- vprint("sync is NULL!\n");
- }
- if(!strcmp(local->name, sync->name)) {
- found = 1;
+ syncpkg_t *sync = NULL;
+ MALLOC(sync, sizeof(syncpkg_t));
+
+ for(j = databases; !found && j; j = j->next) {
+ dbsync_t *dbs = (dbsync_t*)j->data;
+ for(k = dbs->pkgcache; !found && k; k = k->next) {
+ pkginfo_t *pkg = (pkginfo_t*)k->data;
+ if(!strcmp(local->name, pkg->name)) {
+ found = 1;
+ sync->pkg = pkg;
+ sync->dbs = dbs;
+ }
}
}
if(!found) {
@@ -378,7 +371,7 @@ int pacman_sync(pacdb_t *db, PMList *targets)
continue;
}
/* compare versions and see if we need to upgrade */
- cmp = rpmvercmp(local->version, sync->version);
+ cmp = rpmvercmp(local->version, sync->pkg->version);
if(cmp > 0) {
/* local version is newer */
fprintf(stderr, ":: %s-%s: local version is newer\n",
@@ -390,12 +383,12 @@ int pacman_sync(pacdb_t *db, PMList *targets)
continue;
} else {
/* re-fetch the package record with dependency info */
- sync = db_scan(db_sync, sync->name, INFRQ_DESC | INFRQ_DEPENDS);
+ sync->pkg = db_scan(sync->dbs->db, sync->pkg->name, INFRQ_DESC | INFRQ_DEPENDS);
/* add to the targets list */
- if(!is_pkgin(sync, final)) {
- allgood = !resolvedeps(db, db_sync, sync, final, trail);
+ if(!list_isin(final, sync)) {
+ allgood = !resolvedeps(db, databases, sync, final, trail);
/* check again, as resolvedeps could have added our target for us */
- if(!is_pkgin(sync, final)) {
+ if(!list_isin(final, sync)) {
final = list_add(final, sync);
}
}
@@ -408,19 +401,35 @@ int pacman_sync(pacdb_t *db, PMList *targets)
/* process targets */
for(i = targets; i && allgood; i = i->next) {
if(i->data) {
- int cmp;
+ int cmp, found = 0;
pkginfo_t *local;
- pkginfo_t *sync;
+ syncpkg_t *sync = NULL;
+ MALLOC(sync, sizeof(syncpkg_t));
local = db_scan(db, (char*)i->data, INFRQ_DESC);
- sync = db_scan(db_sync, (char*)i->data, INFRQ_DESC | INFRQ_DEPENDS);
- if(sync == NULL) {
- fprintf(stderr, ":: %s: not found in sync db\n", (char*)i->data);
+ //sync = db_scan(db_sync, (char*)i->data, INFRQ_DESC | INFRQ_DEPENDS);
+ for(j = databases; !found && j; j = j->next) {
+ dbsync_t *dbs = (dbsync_t*)j->data;
+ for(k = dbs->pkgcache; !found && k; k = k->next) {
+ pkginfo_t *pkg = (pkginfo_t*)k->data;
+ if(!strcmp((char*)i->data, pkg->name)) {
+ found = 1;
+ sync->dbs = dbs;
+ /* re-fetch the package record with dependency info */
+ sync->pkg = db_scan(sync->dbs->db, pkg->name, INFRQ_DESC | INFRQ_DEPENDS);
+ if(sync->pkg == NULL) {
+ found = 0;
+ }
+ }
+ }
+ }
+ if(!found) {
+ fprintf(stderr, "%s: not found in sync db\n", (char*)i->data);
continue;
}
if(local) {
/* this is an upgrade, compare versions and determine if it is necessary */
- cmp = rpmvercmp(local->version, sync->version);
+ cmp = rpmvercmp(local->version, sync->pkg->version);
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)) {
@@ -434,10 +443,24 @@ int pacman_sync(pacdb_t *db, PMList *targets)
}
}
/* add to targets list */
- if(!is_pkgin(sync, final)) {
- allgood = !resolvedeps(db, db_sync, sync, final, trail);
+ 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) {
+ allgood = !resolvedeps(db, databases, sync, final, trail);
/* check again, as resolvedeps could have added our target for us */
- if(!is_pkgin(sync, final)) {
+ 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);
}
}
@@ -447,7 +470,16 @@ int pacman_sync(pacdb_t *db, PMList *targets)
if(allgood) {
/* check for inter-conflicts and whatnot */
- deps = checkdeps(db, PM_UPGRADE, final);
+ PMList *deps = NULL;
+ PMList *list = NULL;
+
+ for(i = final; i; i = i->next) {
+ syncpkg_t *s = (syncpkg_t*)i->data;
+ if(s) {
+ list = list_add(list, s->pkg);
+ }
+ }
+ deps = checkdeps(db, PM_UPGRADE, list);
if(deps) {
fprintf(stderr, "error: unresolvable conflicts/dependencies:\n");
for(i = deps; i; i = i->next) {
@@ -474,6 +506,12 @@ int pacman_sync(pacdb_t *db, PMList *targets)
/* abort mission */
allgood = 0;
}
+ /* cleanup */
+ for(i = list; i; i = i->next) {
+ i->data = NULL;
+ }
+ list_free(list);
+ list = NULL;
/* list targets */
if(final && final->data) {
@@ -481,18 +519,18 @@ int pacman_sync(pacdb_t *db, PMList *targets)
}
cols = 9;
for(i = final; allgood && i; i = i->next) {
- pkginfo_t *p = (pkginfo_t*)i->data;
- if(p) {
+ syncpkg_t *s = (syncpkg_t*)i->data;
+ if(s && s->pkg) {
char t[PATH_MAX];
- int s;
- snprintf(t, PATH_MAX, "%s-%s ", p->name, p->version);
- s = strlen(t);
- if(s+cols > 78) {
+ int len;
+ snprintf(t, PATH_MAX, "%s-%s ", s->pkg->name, s->pkg->version);
+ len = strlen(t);
+ if(len+cols > 78) {
cols = 9;
fprintf(stderr, "\n%9s", " ");
}
fprintf(stderr, "%s", t);
- cols += s;
+ cols += len;
}
}
printf("\n");
@@ -504,66 +542,96 @@ int pacman_sync(pacdb_t *db, PMList *targets)
}
}
- if(allgood && confirm) {
- PMList *files = NULL;
+ if(allgood && confirm && final && final->data) {
char ldir[PATH_MAX];
int varcache = 1;
+ int done = 0;
+ int count = 0;
+ sync_t *current = NULL;
+ PMList *processed = NULL;
+ PMList *files = NULL;
- /* download targets */
- for(i = final; i; i = i->next) {
- pkginfo_t *p = (pkginfo_t*)i->data;
- if(p) {
- struct stat buf;
- char path[PATH_MAX];
-
- snprintf(path, PATH_MAX, "%svar/cache/pacman/pkg/%s-%s.pkg.tar.gz",
- pmo_root, p->name, p->version);
- if(stat(path, &buf)) {
- /* file is not in the cache dir, so add it to the list */
- snprintf(path, PATH_MAX, "%s-%s.pkg.tar.gz", p->name, p->version);
- files = list_add(files, strdup(path));
- }
+ /* group sync records by repository and download */
+ while(!done) {
+ if(current) {
+ processed = list_add(processed, current);
+ current = NULL;
}
- }
- snprintf(ldir, PATH_MAX, "%svar/cache/pacman/pkg", pmo_root);
+ for(i = final; i; i = i->next) {
+ syncpkg_t *sync = (syncpkg_t*)i->data;
+ if(current == NULL) {
+ /* we're starting on a new repository */
+ if(!list_isin(processed, sync->dbs->sync)) {
+ current = sync->dbs->sync;
+ }
+ }
+ if(current && !strcmp(current->treename, sync->dbs->sync->treename)) {
+ struct stat buf;
+ char path[PATH_MAX];
- if(files) {
- struct stat buf;
-
- printf("\n:: Downloading packages...\n"); fflush(stdout);
- if(stat(ldir, &buf)) {
- mode_t oldmask;
- char parent[PATH_MAX];
-
- /* no cache directory.... try creating it */
- snprintf(parent, PATH_MAX, "%svar/cache/pacman", pmo_root);
- fprintf(stderr, "warning: no %s cache exists. creating...\n", ldir);
- oldmask = umask(0000);
- if(mkdir(parent, 0755) || mkdir(ldir, 0755)) {
- /* couldn't mkdir the cache directory, so fall back to /tmp and unlink
- * the package afterwards.
- */
- fprintf(stderr, "warning: couldn't create package cache, using /tmp instead\n");
- snprintf(ldir, PATH_MAX, "/tmp");
- varcache = 0;
+ snprintf(path, PATH_MAX, "%svar/cache/pacman/pkg/%s-%s.pkg.tar.gz",
+ pmo_root, sync->pkg->name, sync->pkg->version);
+ if(stat(path, &buf)) {
+ /* file is not in the cache dir, so add it to the list */
+ snprintf(path, PATH_MAX, "%s-%s.pkg.tar.gz", sync->pkg->name, sync->pkg->version);
+ files = list_add(files, strdup(path));
+ } else {
+ count++;
+ }
}
- umask(oldmask);
}
- if(downloadfiles(pmc_syncserver, pmc_syncpath, ldir, files)) {
- fprintf(stderr, "error: ftp transfer failed.\n");
- allgood = 0;
+ snprintf(ldir, PATH_MAX, "%svar/cache/pacman/pkg", pmo_root);
+
+ if(files) {
+ struct stat buf;
+
+ printf("\n:: Retrieving packages from %s...\n", current->treename);
+ fflush(stdout);
+ if(stat(ldir, &buf)) {
+ mode_t oldmask;
+ char parent[PATH_MAX];
+
+ /* no cache directory.... try creating it */
+ snprintf(parent, PATH_MAX, "%svar/cache/pacman", pmo_root);
+ fprintf(stderr, "warning: no %s cache exists. creating...\n", ldir);
+ oldmask = umask(0000);
+ mkdir(parent, 0755);
+ if(mkdir(ldir, 0755)) {
+ /* couldn't mkdir the cache directory, so fall back to /tmp and unlink
+ * the package afterwards.
+ */
+ fprintf(stderr, "warning: couldn't create package cache, using /tmp instead\n");
+ snprintf(ldir, PATH_MAX, "/tmp");
+ varcache = 0;
+ }
+ umask(oldmask);
+ }
+ if(downloadfiles(current->servers, ldir, files)) {
+ fprintf(stderr, "error: failed to retrieve some files from %s.\n", current->treename);
+ allgood = 0;
+ }
+ count += list_count(files);
+ list_free(files);
+ files = NULL;
}
+ if(count == list_count(final)) {
+ done = 1;
+ }
+ }
+ printf("\n");
+
+ /* double-check */
+ if(files) {
list_free(files);
files = NULL;
}
-
/* install targets */
for(i = final; allgood && i; i = i->next) {
char *str;
- pkginfo_t *p = (pkginfo_t*)i->data;
- if(p) {
+ syncpkg_t *sync = (syncpkg_t*)i->data;
+ if(sync->pkg) {
MALLOC(str, PATH_MAX);
- snprintf(str, PATH_MAX, "%s/%s-%s.pkg.tar.gz", ldir, p->name, p->version);
+ snprintf(str, PATH_MAX, "%s/%s-%s.pkg.tar.gz", ldir, sync->pkg->name, sync->pkg->version);
files = list_add(files, str);
}
}
@@ -580,22 +648,26 @@ int pacman_sync(pacdb_t *db, PMList *targets)
}
/* cleanup */
- for(i = pkgcache; i; i = i->next) {
- if(i->data) freepkg((pkginfo_t*)i->data);
- i->data = NULL;
- }
for(i = final; i; i = i->next) {
- if(i->data) freepkg((pkginfo_t*)i->data);
+ syncpkg_t *sync = (syncpkg_t*)i->data;
+ if(sync) freepkg(sync->pkg);
+ free(sync);
i->data = NULL;
}
for(i = trail; i; i = i->next) {
/* this list used the same pointers as final, so they're already freed */
i->data = NULL;
}
- list_free(pkgcache);
+ for(i = databases; i; i = i->next) {
+ dbsync_t *dbs = (dbsync_t*)i->data;
+ db_close(dbs->db);
+ list_free(dbs->pkgcache);
+ free(dbs);
+ i->data = NULL;
+ }
+ list_free(databases);
list_free(final);
list_free(trail);
- db_close(db_sync);
return(!allgood);
}
@@ -726,6 +798,7 @@ int pacman_add(pacdb_t *db, PMList *targets)
vprint("extracting files...\n");
for(i = 0; !th_read(tar); i++) {
int nb = 0;
+ int notouch = 0;
char *md5_orig = NULL;
char pathname[PATH_MAX];
strncpy(pathname, th_get_pathname(tar), PATH_MAX);
@@ -746,13 +819,17 @@ int pacman_add(pacdb_t *db, PMList *targets)
if(!stat(expath, &buf) && !S_ISDIR(buf.st_mode)) {
/* file already exists */
- if(!pmo_upgrade) {
- nb = is_in(pathname, info->backup);
+ if(is_in(pathname, pmo_noupgrade)) {
+ notouch = 1;
} else {
- /* op == PM_UPGRADE */
- md5_orig = needbackup(pathname, oldpkg->backup);
- if(md5_orig) {
- nb = 1;
+ if(!pmo_upgrade) {
+ nb = is_in(pathname, info->backup);
+ } else {
+ /* op == PM_UPGRADE */
+ md5_orig = needbackup(pathname, oldpkg->backup);
+ if(md5_orig) {
+ nb = 1;
+ }
}
}
}
@@ -857,7 +934,14 @@ int pacman_add(pacdb_t *db, PMList *targets)
unlink(temp);
FREE(temp);
} else {
- /*vprint(" %s\n", expath);*/
+ if(!notouch) {
+ /*vprint(" %s\n", expath);*/
+ } else {
+ vprint("%s is in NoUpgrade - skipping\n", pathname);
+ strncat(expath, ".pacnew", PATH_MAX);
+ fprintf(stderr, "warning: extracting %s%s as %s\n", pmo_root, pathname, expath);
+ /*tar_skip_regfile(tar);*/
+ }
if(tar_extract_file(tar, expath)) {
fprintf(stderr, "could not extract %s: %s\n", pathname, strerror(errno));
errors++;
@@ -1026,6 +1110,12 @@ int pacman_remove(pacdb_t *db, PMList *targets)
if(needbackup((char*)lp->data, info->backup)) {
nb = 1;
}
+ if(!nb && pmo_upgrade) {
+ /* check pmo_noupgrade */
+ if(is_in((char*)lp->data, pmo_noupgrade)) {
+ nb = 1;
+ }
+ }
snprintf(line, PATH_MAX, "%s%s", pmo_root, (char*)lp->data);
if(lstat(line, &buf)) {
vprint("file %s does not exist\n", line);
@@ -1312,31 +1402,53 @@ int pacman_upgrade(pacdb_t *db, PMList *targets)
}
/* populates *list with packages that need to be installed to satisfy all
- * dependencies (recursive) for *package
+ * dependencies (recursive) for *syncpkg->pkg
*
* make sure *list and *trail are already initialized
*/
-int resolvedeps(pacdb_t *local, pacdb_t *sync, pkginfo_t *package, PMList *list, PMList *trail)
+int resolvedeps(pacdb_t *local, PMList *databases, syncpkg_t *syncpkg, PMList *list, PMList *trail)
{
- pkginfo_t *info;
- PMList *i;
+ PMList *i, *j, *k;
PMList *targ = NULL;
PMList *deps = NULL;
targ = list_new();
- targ = list_add(targ, package);
+ targ = list_add(targ, syncpkg->pkg);
deps = checkdeps(local, PM_ADD, targ);
targ->data = NULL;
list_free(targ);
for(i = deps; i; i = i->next) {
+ int found = 0;
+ syncpkg_t *sync = NULL;
depmissing_t *miss = (depmissing_t*)i->data;
- info = db_scan(sync, miss->depend.name, INFRQ_DESC | INFRQ_DEPENDS);
- if(info == NULL) {
+ MALLOC(sync, sizeof(syncpkg_t));
+
+ /* find the package in one of the repositories */
+ for(j = databases; !found && j; j = j->next) {
+ dbsync_t *dbs = (dbsync_t*)j->data;
+ for(k = dbs->pkgcache; !found && k; k = k->next) {
+ pkginfo_t *pkg = (pkginfo_t*)k->data;
+ if(!strcmp(miss->depend.name, pkg->name)) {
+ found = 1;
+ /* re-fetch the package record with dependency info */
+ sync->pkg = db_scan(dbs->db, pkg->name, INFRQ_DESC | INFRQ_DEPENDS);
+ sync->dbs = dbs;
+ }
+ }
+ }
+ if(!found) {
fprintf(stderr, "error: cannot resolve dependencies for \"%s\":\n", miss->target);
fprintf(stderr, " \"%s\" is not in the package set\n", miss->depend.name);
return(1);
}
- if(is_pkgin(info, list) == 1) {
+ found = 0;
+ for(j = list; j; j = j->next) {
+ syncpkg_t *tmp = (syncpkg_t*)j->data;
+ if(tmp && !strcmp(tmp->pkg->name, sync->pkg->name)) {
+ found = 1;
+ }
+ }
+ if(found) {
/* this dep is already in the target list */
continue;
}
@@ -1344,13 +1456,21 @@ int resolvedeps(pacdb_t *local, pacdb_t *sync, pkginfo_t *package, PMList *list,
fprintf(stderr, "error: %s conflicts with %s\n", miss->target, miss->depend.name);
return(1);
} else if(miss->type == DEPEND) {
- /*printf("resolving %s\n", info->name); fflush(stdout);*/
- if(!is_pkgin(info, trail)) {
- list_add(trail, info);
- if(resolvedeps(local, sync, info, list, trail)) {
+ /*printf("resolving %s\n", sync->pkg->name); fflush(stdout);*/
+ found = 0;
+ for(j = trail; j; j = j->next) {
+ syncpkg_t *tmp = (syncpkg_t*)j->data;
+ if(tmp && !strcmp(tmp->pkg->name, sync->pkg->name)) {
+ found = 1;
+ }
+ }
+ if(!found) {
+ list_add(trail, sync);
+ if(resolvedeps(local, databases, sync, list, trail)) {
return(1);
}
- list_add(list, info);
+ vprint("adding %s-%s\n", sync->pkg->name, sync->pkg->version);
+ list_add(list, sync);
} else {
/* cycle detected -- skip it */
/*printf("cycle detected\n"); fflush(stdout);*/
@@ -1398,7 +1518,7 @@ PMList* checkdeps(pacdb_t *db, unsigned short op, PMList *targets)
if((p = db_scan(db, j->data, INFRQ_DESC | INFRQ_DEPENDS)) == NULL) {
continue;
}
- for(k = p->depends; k; k = k->next) {
+ for(k = p->depends; k && !found; k = k->next) {
if(splitdep(k->data, &depend)) {
continue;
}
diff --git a/src/pacman.h b/src/pacman.h
index 330969ce..37b86853 100644
--- a/src/pacman.h
+++ b/src/pacman.h
@@ -22,7 +22,7 @@
#define _PAC_PACMAN_H
#ifndef PACVER
-#define PACVER "2.0"
+#define PACVER "2.1"
#endif
#ifndef PKGDIR
@@ -50,7 +50,7 @@ int pacman_sync(pacdb_t *db, PMList *targets);
int pacman_deptest(pacdb_t *db, PMList *targets);
PMList* checkdeps(pacdb_t *db, unsigned short op, PMList *targets);
-int resolvedeps(pacdb_t *local, pacdb_t *sync, pkginfo_t *package, PMList *list, PMList *trail);
+int resolvedeps(pacdb_t *local, PMList *databases, syncpkg_t *sync, PMList *list, PMList *trail);
int splitdep(char *depstr, depend_t *depend);
int lckmk(char *file, int retries, unsigned int sleep_secs);
diff --git a/src/pacsync.c b/src/pacsync.c
index 224528f8..a76da444 100644
--- a/src/pacsync.c
+++ b/src/pacsync.c
@@ -41,125 +41,171 @@ static char sync_fnm[25];
/* pacman options */
extern char *pmo_root;
-/* configuration options */
-extern char pmc_syncserver[512];
-extern char pmc_syncpath[512];
-extern char pmc_syncname[512];
+
+/* sync servers */
+extern PMList *pmc_syncs;
int sync_synctree()
{
char ldir[PATH_MAX] = "";
char path[PATH_MAX];
mode_t oldmask;
- char *str;
PMList *files = NULL;
-
- snprintf(ldir, PATH_MAX, "%s%s/%s", pmo_root, PKGDIR, pmc_syncname);
-
- /* remove the old dir */
- vprint("Removing %s (if it exists)\n", ldir);
- rmrf(ldir);
-
- /* make the new dir */
- oldmask = umask(0000);
- mkdir(ldir, 0755);
- umask(oldmask);
-
- /* build out list of one */
- snprintf(path, PATH_MAX, "%s.db.tar.gz", pmc_syncname);
- str = strdup(path);
- files = list_add(files, str);
- if(downloadfiles(pmc_syncserver, pmc_syncpath, ldir, files)) {
+ PMList *i;
+ int success = 0;
+
+ for(i = pmc_syncs; i; i = i->next) {
+ sync_t *sync = (sync_t*)i->data;
+ snprintf(ldir, PATH_MAX, "%s%s", pmo_root, PKGDIR);
+
+ /* build a one-element list */
+ snprintf(path, PATH_MAX, "%s.db.tar.gz", sync->treename);
+ files = list_add(files, strdup(path));
+
+ success = 1;
+ if(downloadfiles(sync->servers, ldir, files)) {
+ fprintf(stderr, "failed to synchronize %s\n", sync->treename);
+ success = 0;
+ }
+ /*printf("\n");*/
list_free(files);
- return(1);
- }
-
- /* uncompress the sync database */
- snprintf(path, PATH_MAX, "%s/%s", ldir, (char*)files->data);
- list_free(files);
- vprint("Unpacking %s...\n", path);
- if(unpack(path, ldir)) {
- return(1);
+ files = NULL;
+ snprintf(path, PATH_MAX, "%s/%s.db.tar.gz", ldir, sync->treename);
+
+ if(success) {
+ snprintf(ldir, PATH_MAX, "%s%s/%s", pmo_root, PKGDIR, sync->treename);
+ /* remove the old dir */
+ vprint("removing %s (if it exists)\n", ldir);
+ rmrf(ldir);
+
+ /* make the new dir */
+ oldmask = umask(0000);
+ mkdir(ldir, 0755);
+ umask(oldmask);
+
+ /* uncompress the sync database */
+ vprint("Unpacking %s...\n", path);
+ if(unpack(path, ldir)) {
+ return(1);
+ }
+ }
+ /* remove the .tar.gz */
+ unlink(path);
}
- /* remove the .tar.gz */
- unlink(path);
-
- return(0);
+ return(!success);
}
-int downloadfiles(char *server, char *remotepath, char *localpath, PMList *files)
+int downloadfiles(PMList *servers, char *localpath, PMList *files)
{
int fsz;
netbuf *control = NULL;
PMList *lp;
- int ret = 0;
+ int done = 0;
+ PMList *complete = NULL;
+ PMList *i;
if(files == NULL) {
return(0);
}
- FtpInit();
- if(!FtpConnect(server, &control)) {
- fprintf(stderr, "error: cannot connect to %s\n", server);
- return(1);
- }
- if(!FtpLogin("anonymous", "arch@guest", control)) {
- fprintf(stderr, "error: anonymous login failed\n");
- FtpQuit(control);
- return(1);
- }
-
-
- if(!FtpChdir(remotepath, control)) {
- fprintf(stderr, "error: could not cwd to %s: %s\n", remotepath,
- FtpLastResponse(control));
- return(1);
- }
-
- /* get each file in the list */
- for(lp = files; lp; lp = lp->next) {
- char output[PATH_MAX];
- int j;
-
- snprintf(output, PATH_MAX, "%s/%s", localpath, (char*)lp->data);
-
- /* passive mode */
- /* TODO: make passive ftp an option */
- if(!FtpOptions(FTPLIB_CONNMODE, FTPLIB_PASSIVE, control)) {
- fprintf(stderr, "warning: failed to set passive mode\n");
+ for(i = servers; i && !done; i = i->next) {
+ server_t *server = (server_t*)i->data;
+
+ if(!server->islocal) {
+ FtpInit();
+ if(!FtpConnect(server->server, &control)) {
+ fprintf(stderr, "error: cannot connect to %s\n", server->server);
+ continue;
+ }
+ if(!FtpLogin("anonymous", "arch@guest", control)) {
+ fprintf(stderr, "error: anonymous login failed\n");
+ FtpQuit(control);
+ continue;
+ }
+ if(!FtpChdir(server->path, control)) {
+ fprintf(stderr, "error: could not cwd to %s: %s\n", server->path,
+ FtpLastResponse(control));
+ continue;
+ }
}
- if(!FtpSize((char*)lp->data, &fsz, FTPLIB_IMAGE, control)) {
- fprintf(stderr, "warning: failed to get filesize for %s\n", (char*)lp->data);
- }
-
- /* set up our progress bar's callback */
- FtpOptions(FTPLIB_CALLBACK, (long)log_progress, control);
- FtpOptions(FTPLIB_IDLETIME, (long)1000, control);
- FtpOptions(FTPLIB_CALLBACKARG, (long)&fsz, control);
- FtpOptions(FTPLIB_CALLBACKBYTES, (10*1024), control);
+ /* get each file in the list */
+ for(lp = files; lp; lp = lp->next) {
+ char output[PATH_MAX];
+ int j;
+ char *fn = (char*)lp->data;
+
+ if(is_in(fn, complete)) {
+ continue;
+ }
+
+ snprintf(output, PATH_MAX, "%s/%s", localpath, fn);
+ strncpy(sync_fnm, lp->data, 24);
+ for(j = strlen(sync_fnm); j < 24; j++) {
+ sync_fnm[j] = ' ';
+ }
+ sync_fnm[24] = '\0';
+
+ if(!server->islocal) {
+ /* passive mode */
+ /* TODO: make passive ftp an option */
+ if(!FtpOptions(FTPLIB_CONNMODE, FTPLIB_PASSIVE, control)) {
+ fprintf(stderr, "warning: failed to set passive mode\n");
+ }
+ if(!FtpSize(fn, &fsz, FTPLIB_IMAGE, control)) {
+ fprintf(stderr, "warning: failed to get filesize for %s\n", fn);
+ }
+ /* set up our progress bar's callback */
+ FtpOptions(FTPLIB_CALLBACK, (long)log_progress, control);
+ FtpOptions(FTPLIB_IDLETIME, (long)1000, control);
+ FtpOptions(FTPLIB_CALLBACKARG, (long)&fsz, control);
+ FtpOptions(FTPLIB_CALLBACKBYTES, (10*1024), control);
- strncpy(sync_fnm, lp->data, 24);
- for(j = strlen(sync_fnm); j < 24; j++) {
- sync_fnm[j] = ' ';
+ if(!FtpGet(output, lp->data, FTPLIB_IMAGE, control)) {
+ fprintf(stderr, "\nfailed downloading %s from %s: %s\n",
+ fn, server->server, FtpLastResponse(control));
+ /* unlink the file */
+ unlink(output);
+ } else {
+ log_progress(control, fsz, &fsz);
+ complete = list_add(complete, fn);
+ }
+ printf("\n");
+ fflush(stdout);
+ } else {
+ /* local repository, just copy the file */
+ char src[PATH_MAX], dest[PATH_MAX];
+ snprintf(src, PATH_MAX, "%s%s", server->path, fn);
+ snprintf(dest, PATH_MAX, "%s/%s", localpath, fn);
+ vprint("copying %s to %s\n", src, dest);
+ if(copyfile(src, dest)) {
+ fprintf(stderr, "failed copying %s\n", src);
+ } else {
+ char out[56];
+ printf("%s [", sync_fnm);
+ strncpy(out, server->path, 33);
+ printf("%s", out);
+ for(j = strlen(out); j < 33; j++) {
+ printf(" ");
+ }
+ fputs("] 100% | LOCAL\n", stdout);
+ fflush(stdout);
+
+ complete = list_add(complete, fn);
+ }
+ }
+ }
+ if(list_count(complete) == list_count(files)) {
+ done = 1;
}
- sync_fnm[24] = '\0';
- if(!FtpGet(output, lp->data, FTPLIB_IMAGE, control)) {
- fprintf(stderr, "\nerror: could not download %s: %s\n", (char*)lp->data,
- FtpLastResponse(control));
- /* unlink the file */
- unlink(output);
- ret = 1;
- } else {
- log_progress(control, fsz, &fsz);
+
+ if(!server->islocal) {
+ FtpQuit(control);
}
- printf("\n");
- fflush(stdout);
}
-
- FtpQuit(control);
- return(ret);
+
+ return(!done);
}
static int log_progress(netbuf *ctl, int xfered, void *arg)
diff --git a/src/pacsync.h b/src/pacsync.h
index d7c666f3..1838a684 100644
--- a/src/pacsync.h
+++ b/src/pacsync.h
@@ -21,8 +21,31 @@
#ifndef _PAC_PACSYNC_H
#define _PAC_PACSYNC_H
+typedef struct __server_t {
+ unsigned short islocal;
+ char* server;
+ char* path;
+} server_t;
+
+typedef struct __sync_t {
+ char* treename;
+ PMList *servers;
+} sync_t;
+
+/* linking structs */
+typedef struct __dbsync_t {
+ pacdb_t *db;
+ sync_t *sync;
+ PMList *pkgcache;
+} dbsync_t;
+
+typedef struct __syncpkg_t {
+ pkginfo_t *pkg;
+ dbsync_t *dbs;
+} syncpkg_t;
+
int sync_synctree();
-int downloadfiles(char *server, char *remotepath, char *localpath, PMList *files);
+int downloadfiles(PMList *servers, char *localpath, PMList *files);
#endif
diff --git a/src/util.c b/src/util.c
index 1fe2e037..b5930bcf 100644
--- a/src/util.c
+++ b/src/util.c
@@ -34,6 +34,7 @@
#include "package.h"
#include "db.h"
#include "util.h"
+#include "pacsync.h"
#include "pacman.h"
extern char* pmo_root;
@@ -54,11 +55,9 @@ 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 PMList *pmo_noupgrade;
-extern char pmc_syncserver[512];
-extern char pmc_syncname[512];
-extern char pmc_syncpath[512];
-
+extern PMList *pmc_syncs;
extern PMList *pm_targets;
/* borrowed and modifed from Per Liden's pkgutils (http://crux.nu) */
@@ -221,6 +220,7 @@ int parseargs(int op, int argc, char **argv)
return(0);
}
+#define min(X, Y) ((X) < (Y) ? (X) : (Y))
int parseconfig(char *configfile)
{
FILE *fp = NULL;
@@ -228,6 +228,8 @@ int parseconfig(char *configfile)
char *ptr = NULL;
char *key = NULL;
int linenum = 0;
+ char section[256] = "";
+ sync_t *sync = NULL;
if((fp = fopen(configfile, "r")) == NULL) {
perror(configfile);
@@ -243,25 +245,126 @@ int parseconfig(char *configfile)
if(line[0] == '#') {
continue;
}
- ptr = line;
- key = strsep(&ptr, "=");
- if(key == NULL || ptr == NULL) {
- fprintf(stderr, "syntax error in config file (line %d)\n", linenum);
+ 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 {
- trim(key);
- key = strtoupper(key);
- trim(ptr);
- if(!strcmp(key, "SYNC_SERVER")) {
- strncpy(pmc_syncserver, ptr, sizeof(pmc_syncserver)-1);
- } else if(!strcmp(key, "SYNC_TREE_PATH")) {
- strncpy(pmc_syncpath, ptr, sizeof(pmc_syncpath)-1);
- } else if(!strcmp(key, "SYNC_TREE_NAME")) {
- strncpy(pmc_syncname, ptr, sizeof(pmc_syncname)-1);
+ /* 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 || ptr == NULL) {
+ fprintf(stderr, "config: line %d: syntax error\n", linenum);
+ return(1);
} else {
- fprintf(stderr, "Syntax error in description file line %d\n", linenum);
+ trim(key);
+ key = strtoupper(key);
+ 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 {
+ 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';
}
}
- line[0] = '\0';
}
fclose(fp);
@@ -272,7 +375,7 @@ int copyfile(char *src, char *dest)
{
FILE *in, *out;
size_t len;
- char buf[1025];
+ char buf[4097];
in = fopen(src, "r");
if(in == NULL) {
@@ -283,7 +386,7 @@ int copyfile(char *src, char *dest)
return(1);
}
- while((len = fread(buf, 1, 1024, in))) {
+ while((len = fread(buf, 1, 4096, in))) {
fwrite(buf, 1, len, out);
}