summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJudd Vinet <judd@archlinux.org>2004-04-29 21:43:18 +0200
committerJudd Vinet <judd@archlinux.org>2004-04-29 21:43:18 +0200
commit4ad864462043c61d19861e4b7cacf6610ae9ce7f (patch)
tree9452939bf7d7b647e0d6c8b5876810f47fad2e4e
parent4cb6a179b3b23fff7208628438d59783e9e65dfc (diff)
downloadpacman-4ad864462043c61d19861e4b7cacf6610ae9ce7f.tar.gz
pacman-4ad864462043c61d19861e4b7cacf6610ae9ce7f.tar.xz
Imported from pacman-2.7.8.tar.gz
-rw-r--r--ChangeLog20
-rw-r--r--Makefile.in2
-rw-r--r--doc/makepkg.8.in17
-rw-r--r--doc/pacman.8.in17
-rw-r--r--etc/makepkg.conf5
-rw-r--r--etc/pacman.conf2
-rw-r--r--libftp/ftplib.c6
-rwxr-xr-xscripts/gensync25
-rwxr-xr-xscripts/makepkg10
-rwxr-xr-xscripts/makeworld2
-rw-r--r--src/db.c79
-rw-r--r--src/db.h1
-rw-r--r--src/package.c33
-rw-r--r--src/package.h3
-rw-r--r--src/pacman.c249
-rw-r--r--src/pacman.h6
-rw-r--r--src/pacsync.c35
17 files changed, 388 insertions, 124 deletions
diff --git a/ChangeLog b/ChangeLog
index e82b3e16..8c511a06 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,25 @@
VERSION DESCRIPTION
-----------------------------------------------------------------------------
+2.7.8 - added post_remove scriptlet support
+ - added -Qs option (bug #854)
+ - a provisio does not imply conflict, to make a provisio target
+ conflict with anything else that provides the same thing, you
+ can now do this by specifying the provisio target as both a
+ provides and a conflict, eg:
+ conflicts=('x-server')
+ provides=('x-server')
+ - cleaned up the download progress bar a bit
+ - added %o parameter to XferCommand so wget can resume properly
+ - fixed a segfault in downloadfiles() (bug #787)
+ - patches from Oliver Burnett-Hall
+ - gensync uses a better temp dir (bug #774)
+ - PKGDEST can be set in makepkg.conf (bug #783)
+ - patches from Aurelien Foret
+ - segfault fix, couple memory leaks
+ - more sanity checks in "provides" searches
+ - fixed a little display bug in the progress bar
+ - made -Qip look like -Qi
+ - -Sc now removes OLD packages from cache, use -Scc for all
2.7.7 - added an XferCommand directive that will make pacman use an
external download utility like wget
- added a license field to package meta-data
diff --git a/Makefile.in b/Makefile.in
index dcf070f3..8bfeae36 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.7.7
+PACVER = 2.7.8
TOPDIR = @srcdir@
SRCDIR = $(TOPDIR)/src/
diff --git a/doc/makepkg.8.in b/doc/makepkg.8.in
index 041d4fd1..6547cb7e 100644
--- a/doc/makepkg.8.in
+++ b/doc/makepkg.8.in
@@ -1,4 +1,4 @@
-.TH makepkg 8 "December 20, 2003" "makepkg #VERSION#" ""
+.TH makepkg 8 "April 27, 2004" "makepkg #VERSION#" ""
.SH NAME
makepkg \- package build utility
.SH SYNOPSIS
@@ -131,6 +131,10 @@ script is run after all files have been upgraded.
.B pre_remove
script is run right before files are removed.
+.TP
+.B post_remove
+script is run right after files are removed.
+
.RE
To use this feature, just create a file (eg, pkgname.install) and put it in
the same directory as the PKGBUILD script. Then use the \fIinstall\fP directive:
@@ -172,14 +176,21 @@ pre_remove() {
/bin/true
}
+# arg 1: the old package version
+post_remove() {
+ #
+ # do post-remove stuff here
+ #
+ /bin/true
+}
+
op=$1
shift
-
$op $*
.fi
.RE
-This template is also available in your ABS tree (/usr/abs/install.proto).
+This template is also available in your ABS tree (/var/abs/install.proto).
.SH PKGBUILD Directives
.TP
diff --git a/doc/pacman.8.in b/doc/pacman.8.in
index 33b43636..32cd42db 100644
--- a/doc/pacman.8.in
+++ b/doc/pacman.8.in
@@ -1,4 +1,4 @@
-.TH pacman 8 "April 14, 2004" "pacman #VERSION#" ""
+.TH pacman 8 "April 29, 2004" "pacman #VERSION#" ""
.SH NAME
pacman \- package manager utility
.SH SYNOPSIS
@@ -101,9 +101,11 @@ Output more status and error messages.
.SH SYNC OPTIONS
.TP
.B "\-c, \-\-clean"
-Remove packages from the cache. When pacman downloads packages,
+Remove old packages from the cache. When pacman downloads packages,
it saves them in \fI/var/cache/pacman/pkg\fP. If you need to free up
diskspace, you can remove these packages by using the --clean option.
+Using one --clean (or -c) switch will only remove \fIold\fP packages.
+Use it twice to remove \fIall\fP packages from the cache.
.TP
.B "\-g, \-\-groups"
Display all the members for each package group specified. If no group
@@ -163,6 +165,10 @@ Search for the package that owns <file>.
Tells pacman that the package supplied on the command line is a
file, not an entry in the database. Pacman will decompress the
file and query it. This is useful with \fB--info\fP and \fB--list\fP.
+.TP
+.B "\-s, \-\-search <string>"
+This will search each locally-installed package for names or descriptions
+that contains <string>.
.SH HANDLING CONFIG FILES
pacman uses the same logic as rpm to determine action against files
that are designated to be backed up. During an upgrade, it uses 3
@@ -230,8 +236,11 @@ If set, pacman will use this proxy server for all ftp/http transfers.
.TP
.B "XferCommand = /path/to/command %u"
If set, pacman will use this external program to download all remote files.
-All instances of \fB%u\fP will be replaced with the URL to be downloaded.
-This is useful for users who experience problems with pacman's built-in http/ftp
+All instances of \fB%u\fP will be replaced with the URL to be downloaded. If
+present, instances of \fB%o\fP will be replaced with the local filename, plus a
+".part" extension, which allows programs like wget to do file resumes properly.
+
+This option is useful for users who experience problems with pacman's built-in http/ftp
support, or need the more advanced proxy support that comes with utilities like
wget.
.TP
diff --git a/etc/makepkg.conf b/etc/makepkg.conf
index af29d74d..0d0809a0 100644
--- a/etc/makepkg.conf
+++ b/etc/makepkg.conf
@@ -28,6 +28,9 @@ export USE_FAKEROOT="y"
# Enable colorized output messages
export USE_COLOR="n"
-# if you want your name to show up in the packages you build, set this.
+# Specify a fixed directory where all packages will be placed
+#export PKGDEST=/home/packages
+
+# If you want your name to show up in the packages you build, set this.
#export PACKAGER="John Doe <john@doe.com>"
diff --git a/etc/pacman.conf b/etc/pacman.conf
index 07ef718d..6ecb832a 100644
--- a/etc/pacman.conf
+++ b/etc/pacman.conf
@@ -23,7 +23,7 @@ NoUpgrade = etc/fstab etc/raidtab
NoUpgrade = etc/rc.conf etc/rc.local
NoUpgrade = etc/modprobe.conf etc/modules.conf
NoUpgrade = etc/lilo.conf boot/grub/menu.lst
-#XferCommand = /usr/bin/wget --passive-ftp -c %u
+#XferCommand = /usr/bin/wget --passive-ftp -c -O %o %u
#
# REPOSITORIES
diff --git a/libftp/ftplib.c b/libftp/ftplib.c
index 68165100..1e299b5b 100644
--- a/libftp/ftplib.c
+++ b/libftp/ftplib.c
@@ -1562,6 +1562,8 @@ GLOBALREF int HttpGet(const char *host, const char *outputfile, const char *path
*/
GLOBALREF void HttpQuit(netbuf *nControl)
{
- net_close(nControl->handle);
- free(nControl);
+ if(nControl) {
+ net_close(nControl->handle);
+ free(nControl);
+ }
}
diff --git a/scripts/gensync b/scripts/gensync
index e7c7724c..23347630 100755
--- a/scripts/gensync
+++ b/scripts/gensync
@@ -20,15 +20,15 @@
# USA.
#
-myver='2.7.7'
+myver='2.7.8'
usage() {
echo "gensync $myver"
echo "usage: $0 <root> <destfile> [package_directory]"
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 "from <root>. gensync builds the database in a temporary directory"
+ echo "and then compresses it to <destfile>."
echo
echo "gensync will calculate md5sums of packages in <destdir>, unless an"
echo "alternate [package_directory] is specified."
@@ -66,7 +66,7 @@ db_write_entry()
unset pkgname pkgver pkgrel pkgdesc
unset groups replaces provides depends conflicts
source $1 || return 1
- cd /tmp/.gensync
+ cd $gstmpdir
mkdir $pkgname-$pkgver-$pkgrel
cd $pkgname-$pkgver-$pkgrel
# desc
@@ -143,43 +143,40 @@ pkgdir=
if [ "$3" != "" ]; then
pkgdir=$3
fi
-
-rm -rf /tmp/.gensync || exit 1
-mkdir -p /tmp/.gensync || exit 1
+gstmpdir=$(mktemp -dt gensync.XXXXXXXXXX) || exit 1
if [ ! -d $rootdir ]; then
echo "gensync: invalid root dir: $rootdir" >&2
- rm -rf /tmp/.gensync
+ rm -rf $gstmpdir
exit 1
fi
echo "gensync: building database entries, generating md5sums..." >&2
cd `dirname $2`
-#for category in `find $rootdir/* -type d -maxdepth 0`; do
for file in `find $rootdir/* -name PKGBUILD`; do
pkgmd5sum=`get_md5checksum $file $pkgdir`
if [ -z $pkgmd5sum ]; then
echo "gensync: error generating checksum for $file" >&2
- rm -rf /tmp/.gensync
+ rm -rf $gstmpdir
exit 1
fi
db_write_entry $file
if [ $? -gt 0 ]; then
echo "gensync: error writing entry for $file" >&2
- rm -rf /tmp/.gensync
+ rm -rf $gstmpdir
exit 1
fi
done
echo "gensync: compressing to $destfile..." >&2
-cd /tmp/.gensync
+cd $gstmpdir
tar c * | gzip -9 >$destfile
if [ $? -gt 0 ]; then
echo "gensync: error writing to $destfile" >&2
- rm -rf /tmp/.gensync
+ rm -rf $gstmpdir
exit 1
fi
-rm -rf /tmp/.gensync
+rm -rf $gstmpdir
exit 0
diff --git a/scripts/makepkg b/scripts/makepkg
index d53bdd17..c0977b9f 100755
--- a/scripts/makepkg
+++ b/scripts/makepkg
@@ -20,8 +20,9 @@
# USA.
#
-myver='2.7.7'
+myver='2.7.8'
startdir=`pwd`
+PKGDEST=$startdir
USE_COLOR="n"
# source Arch's abs.conf if it's present
@@ -208,7 +209,6 @@ FORCE=0
NOEXTRACT=0
NOSTRIP=0
RMDEPS=0
-PKGDEST=$startdir
BUILDSCRIPT="./PKGBUILD"
ARGLIST=$@
@@ -275,7 +275,11 @@ while [ "$#" -ne "0" ]; do
done
# convert a (possibly) relative path to absolute
-cd $PKGDEST
+cd $PKGDEST 2>/dev/null
+if [ $? -ne 0 ]; then
+ error "Package destination directory does not exist or permission denied."
+ exit 1
+fi
PKGDEST=`pwd`
cd -
diff --git a/scripts/makeworld b/scripts/makeworld
index 1e6c7e6b..0397aa56 100755
--- a/scripts/makeworld
+++ b/scripts/makeworld
@@ -21,7 +21,7 @@
#
toplevel=`pwd`
-version="2.7.7"
+version="2.7.8"
usage() {
echo "makeworld version $version"
diff --git a/src/db.c b/src/db.c
index 29135afd..3a208bea 100644
--- a/src/db.c
+++ b/src/db.c
@@ -71,7 +71,7 @@ PMList* db_loadpkgs(pacdb_t *db)
PMList *cache = NULL;
rewinddir(db->dir);
- while((info = db_scan(db, NULL, INFRQ_DESC)) != NULL) {
+ while((info = db_scan(db, NULL, INFRQ_DESC | INFRQ_DEPENDS)) != NULL) {
/* add to the collective */
/* we load all package names into a linear array first, so qsort can handle it */
if(arr == NULL) {
@@ -110,12 +110,12 @@ pkginfo_t* db_scan(pacdb_t *db, char *target, unsigned int inforeq)
if(target != NULL) {
/* search for a specific package (by name only) */
rewinddir(db->dir);
- /* read the . and .. first */
- ent = readdir(db->dir);
- ent = readdir(db->dir);
-
ent = readdir(db->dir);
while(!found && ent != NULL) {
+ if(!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, "..")) {
+ ent = readdir(db->dir);
+ continue;
+ }
strncpy(name, ent->d_name, 255);
/* truncate the string at the second-to-last hyphen, */
/* which will give us the package name */
@@ -137,14 +137,14 @@ pkginfo_t* db_scan(pacdb_t *db, char *target, unsigned int inforeq)
} else {
/* normal iteration */
ent = readdir(db->dir);
- if(ent && !strcmp(ent->d_name, ".")) {
- ent = readdir(db->dir);
+ if(ent == NULL) {
+ return(NULL);
}
- if(ent && !strcmp(ent->d_name, "..")) {
+ if(!strcmp(ent->d_name, ".")) {
ent = readdir(db->dir);
}
- if(ent == NULL) {
- return(NULL);
+ if(!strcmp(ent->d_name, "..")) {
+ ent = readdir(db->dir);
}
}
return(db_read(db, ent, inforeq));
@@ -454,6 +454,65 @@ int db_write(pacdb_t *db, pkginfo_t *info)
return(0);
}
+void db_search(pacdb_t *db, PMList *cache, const char *treename, PMList *needles)
+{
+ PMList *i, *j;
+ if(needles == NULL || needles->data == NULL) {
+ return;
+ }
+
+ for(i = needles; i; i = i->next) {
+ char *targ = strdup(i->data);
+ strtoupper(targ);
+ for(j = cache; j; j = j->next) {
+ pkginfo_t *pkg = (pkginfo_t*)j->data;
+ char *haystack;
+ int match = 0;
+ /* check name */
+ haystack = strdup(pkg->name);
+ strtoupper(haystack);
+ if(strstr(haystack, targ)) {
+ match = 1;
+ }
+ FREE(haystack);
+
+ /* check description */
+ if(!match) {
+ haystack = strdup(pkg->desc);
+ strtoupper(haystack);
+ if(strstr(haystack, targ)) {
+ match = 1;
+ }
+ FREE(haystack);
+ }
+
+ /* check provides */
+ if(!match) {
+ PMList *m;
+ pkginfo_t *info = db_scan(db, pkg->name, INFRQ_DESC | INFRQ_DEPENDS);
+ if(info != NULL) {
+ for(m = info->provides; m; m = m->next) {
+ haystack = strdup(m->data);
+ strtoupper(haystack);
+ if(strstr(haystack, targ)) {
+ match = 1;
+ }
+ FREE(haystack);
+ }
+ FREEPKG(info);
+ }
+ }
+
+ if(match) {
+ printf("%s/%s %s\n ", treename, pkg->name, pkg->version);
+ indentprint(pkg->desc, 4);
+ printf("\n");
+ }
+ }
+ FREE(targ);
+ }
+}
+
PMList* db_find_conflicts(pacdb_t *db, PMList *targets, char *root)
{
diff --git a/src/db.h b/src/db.h
index 8d5282cf..6160a5f0 100644
--- a/src/db.h
+++ b/src/db.h
@@ -41,6 +41,7 @@ PMList* db_loadpkgs(pacdb_t *db);
pkginfo_t* db_scan(pacdb_t *db, char *target, unsigned int inforeq);
pkginfo_t* db_read(pacdb_t *db, struct dirent *ent, unsigned int inforeq);
int db_write(pacdb_t *db, pkginfo_t *info);
+void db_search(pacdb_t *db, PMList *cache, const char *treename, PMList *needles);
PMList* db_find_conflicts(pacdb_t *db, PMList* targets, char *root);
PMList *whatprovides(pacdb_t *db, char* package);
PMList *find_groups(pacdb_t *db);
diff --git a/src/package.c b/src/package.c
index 04153fb1..e7567d23 100644
--- a/src/package.c
+++ b/src/package.c
@@ -30,7 +30,7 @@
#include "util.h"
#include "package.h"
-pkginfo_t* load_pkg(char *pkgfile, unsigned short output)
+pkginfo_t* load_pkg(char *pkgfile)
{
char *expath;
int i;
@@ -66,7 +66,7 @@ pkginfo_t* load_pkg(char *pkgfile, unsigned short output)
mkstemp(descfile);
tar_extract_file(tar, descfile);
/* parse the info file */
- parse_descfile(descfile, info, &backup, output);
+ parse_descfile(descfile, info, &backup, 0);
if(!strlen(info->name)) {
fprintf(stderr, "load_pkg: missing package name in %s.\n", pkgfile);
FREEPKG(info);
@@ -379,4 +379,33 @@ void dump_pkg_sync(pkginfo_t *info)
printf("\nMD5 Sum : %s\n", info->md5sum);
}
+int split_pkgname(char *pkg, char **name, char **version)
+{
+ char tmp[256];
+ char *p, *q;
+
+ strncpy(tmp, pkg, 256);
+
+ p = strstr(tmp, ".pkg.tar.gz");
+ if(p == NULL) {
+ return(-1);
+ }
+ *p = 0;
+
+ for(q = --p; *q && *q != '-'; q--);
+ if(*q != '-' || q == tmp) {
+ return(-1);
+ }
+ for(p = --q; *p && *p != '-'; p--);
+ if(*p != '-' || p == tmp) {
+ return(-1);
+ }
+ *version = strdup(p+1);
+ *p = 0;
+
+ *name = strdup(tmp);
+
+ return(0);
+}
+
/* vim: set ts=2 sw=2 noet: */
diff --git a/src/package.h b/src/package.h
index 8d6f458c..6dcd8cf3 100644
--- a/src/package.h
+++ b/src/package.h
@@ -75,7 +75,7 @@ typedef struct __depmissing_t {
depend_t depend;
} depmissing_t;
-pkginfo_t* load_pkg(char *pkgfile, unsigned short output);
+pkginfo_t* load_pkg(char *pkgfile);
int parse_descfile(char *descfile, pkginfo_t *info, PMList **backup, int output);
pkginfo_t* newpkg();
void freepkg(pkginfo_t *pkg);
@@ -83,6 +83,7 @@ int pkgcmp(const void *p1, const void *p2);
int is_pkgin(pkginfo_t *needle, PMList *haystack);
void dump_pkg_full(pkginfo_t *info);
void dump_pkg_sync(pkginfo_t *info);
+int split_pkgname(char *pkg, char **name, char **version);
#endif
/* vim: set ts=2 sw=2 noet: */
diff --git a/src/pacman.c b/src/pacman.c
index e2db8721..3b5d3ddb 100644
--- a/src/pacman.c
+++ b/src/pacman.c
@@ -35,6 +35,7 @@
#include <zlib.h>
#include <syslog.h>
#include <libtar.h>
+#include <dirent.h>
/* pacman */
#include "rpmvercmp.h"
#include "md5.h"
@@ -68,6 +69,7 @@ unsigned short pmo_q_info = 0;
unsigned short pmo_q_list = 0;
unsigned short pmo_q_orphans = 0;
unsigned short pmo_q_owns = 0;
+unsigned short pmo_q_search = 0;
unsigned short pmo_r_cascade = 0;
unsigned short pmo_r_dbonly = 0;
unsigned short pmo_r_recurse = 0;
@@ -322,21 +324,96 @@ int pacman_sync(pacdb_t *db, PMList *targets)
}
if(pmo_s_clean) {
- mode_t oldmask;
+ if(pmo_s_clean == 1) {
+ /* incomplete cleanup: we keep latest packages and partial downloads */
+ DIR *dir;
+ struct dirent *ent;
+ PMList *cache = NULL;
+ PMList *clean = NULL;
+ PMList *i, *j;
+
+ printf("removing old packages from cache... ");
+ dir = opendir("/var/cache/pacman/pkg");
+ if(dir == NULL) {
+ fprintf(stderr, "error: could not access cache directory\n");
+ return(1);
+ }
+ rewinddir(dir);
+ while((ent = readdir(dir)) != NULL) {
+ if(!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, "..")) {
+ continue;
+ }
+ cache = list_add(cache, strdup(ent->d_name));
+ }
+ closedir(dir);
- printf("removing packages from cache... ");
- if(rmrf("/var/cache/pacman/pkg")) {
- fprintf(stderr, "error: could not remove cache directory: %s\n", strerror(errno));
- return(1);
- }
+ for(i = cache; i; i = i->next) {
+ char *str = (char *)i->data;
+ char *name, *version;
- oldmask = umask(0000);
- if(makepath("/var/cache/pacman/pkg")) {
- fprintf(stderr, "error: could not create new cache directory: %s\n", strerror(errno));
- return(1);
- }
- umask(oldmask);
+ if(split_pkgname(str, &name, &version) != 0) {
+ clean = list_add(clean, strdup(str));
+ continue;
+ }
+ /* we keep partially downloaded files */
+ if(strstr(str, ".pkg.tar.gz.part")) {
+ FREE(name);
+ FREE(version);
+ continue;
+ }
+ for(j = i->next; j; j = j->next) {
+ char *s = (char *)j->data;
+ char *n, *v;
+ if(split_pkgname(s, &n, &v) != 0) {
+ continue;
+ }
+ if(!strcmp(name, n)) {
+ char *ptr;
+ if(rpmvercmp(version, v) < 0) {
+ ptr = str;
+ } else {
+ ptr = s;
+ }
+ if(!is_in(ptr, clean)) {
+ clean = list_add(clean, strdup(ptr));
+ }
+ }
+ FREE(n);
+ FREE(v);
+ }
+ FREE(name);
+ FREE(version);
+ }
+ FREELIST(cache);
+
+ for(i = clean; i; i = i->next) {
+ char path[PATH_MAX];
+
+ snprintf(path, PATH_MAX, "%s%s/%s", pmo_root, CACHEDIR, (char *)i->data);
+ unlink(path);
+ }
+ FREELIST(clean);
+ } else {
+ /* full cleanup */
+ mode_t oldmask;
+ char path[PATH_MAX];
+
+ snprintf(path, PATH_MAX, "%s%s", pmo_root, CACHEDIR);
+
+ printf("removing all packages from cache... ");
+ if(rmrf(path)) {
+ fprintf(stderr, "error: could not remove cache directory: %s\n", strerror(errno));
+ return(1);
+ }
+
+ oldmask = umask(0000);
+ if(makepath(path)) {
+ fprintf(stderr, "error: could not create new cache directory: %s\n", strerror(errno));
+ return(1);
+ }
+ umask(oldmask);
+ }
printf("done.\n");
return(0);
}
@@ -374,53 +451,9 @@ int pacman_sync(pacdb_t *db, PMList *targets)
if(pmo_s_search) {
/* search sync databases */
if(targets) {
- for(i = targets; i; i = i->next) {
- char *targ = strdup(i->data);
- strtoupper(targ);
- 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;
- PMList *m;
- int match = 0;
- /* check name */
- haystack = strdup(pkg->name);
- strtoupper(haystack);
- if(strstr(haystack, targ)) {
- match = 1;
- }
- FREE(haystack);
-
- /* check description */
- haystack = strdup(pkg->desc);
- strtoupper(haystack);
- if(strstr(haystack, targ)) {
- match = 1;
- }
- FREE(haystack);
-
- if(!match) {
- pkg = db_scan(dbs->db, pkg->name, INFRQ_DESC | INFRQ_DEPENDS);
- /* check provides */
- for(m = pkg->provides; m; m = m->next) {
- haystack = strdup(m->data);
- strtoupper(haystack);
- if(strstr(haystack, targ)) {
- match = 1;
- }
- FREE(haystack);
- }
- }
-
- if(match) {
- printf("%s/%s %s\n ", dbs->sync->treename, pkg->name, pkg->version);
- indentprint(pkg->desc, 4);
- printf("\n");
- }
- }
- }
- FREE(targ);
+ for(j = databases; j; j = j->next) {
+ dbsync_t *dbs = (dbsync_t*)j->data;
+ db_search(dbs->db, dbs->pkgcache, dbs->sync->treename, targets);
}
} else {
for(j = databases; j; j = j->next) {
@@ -1381,7 +1414,7 @@ int pacman_add(pacdb_t *db, PMList *targets)
for(targ = targets; targ; targ = targ->next) {
/* Populate the package struct */
vprint("reading %s... ", (char*)targ->data);
- info = load_pkg((char*)targ->data, 0);
+ info = load_pkg((char*)targ->data);
if(info == NULL) {
return(1);
}
@@ -1957,7 +1990,7 @@ int pacman_remove(pacdb_t *db, PMList *targets)
depmissing_t* miss = (depmissing_t*)j->data;
printf(" %s: is required by %s\n", miss->target, miss->depend.name);
}
- list_free(alltargs);
+ FREELISTPKGS(alltargs);
list_free(lp);
return(1);
}
@@ -1973,7 +2006,7 @@ int pacman_remove(pacdb_t *db, PMList *targets)
list_display("\nTargets:", alltargs);
/* get confirmation */
if(yesno("\nDo you want to remove these packages? [Y/n] ") == 0) {
- list_free(alltargs);
+ FREELISTPKGS(alltargs);
return(1);
}
}
@@ -2048,6 +2081,18 @@ int pacman_remove(pacdb_t *db, PMList *targets)
}
}
+ if(!pmo_upgrade) {
+ /* run the post-remove script if it exists */
+ snprintf(pm_install, PATH_MAX, "%s%s/%s/%s-%s/install", pmo_root, pmo_dbpath, db->treename, info->name, info->version);
+ if(!stat(pm_install, &buf)) {
+ vprint("Executing post-remove script...\n");
+ snprintf(pm_install, PATH_MAX, "%s/%s/%s-%s/install", pmo_dbpath, db->treename, info->name, info->version);
+ snprintf(line, PATH_MAX, "chroot %s /bin/sh %s post_remove %s", pmo_root, pm_install, info->version);
+
+ system(line);
+ }
+ }
+
/* remove the package from the database */
snprintf(line, PATH_MAX, "%s%s/%s/%s-%s", pmo_root, pmo_dbpath, db->treename,
info->name, info->version);
@@ -2118,7 +2163,7 @@ int pacman_remove(pacdb_t *db, PMList *targets)
}
}
- FREELIST(alltargs);
+ FREELISTPKGS(alltargs);
/* run ldconfig if it exists */
snprintf(line, PATH_MAX, "%setc/ld.so.conf", pmo_root);
@@ -2143,6 +2188,11 @@ int pacman_query(pacdb_t *db, PMList *targets)
PMList *targ, *lp, *q;
int done = 0;
+ if(pmo_q_search) {
+ db_search(db, pm_packages, "local", targets);
+ return(0);
+ }
+
for(targ = targets; !done; targ = (targ ? targ->next : NULL)) {
if(targets == NULL) {
done = 1;
@@ -2187,12 +2237,13 @@ int pacman_query(pacdb_t *db, PMList *targets)
fprintf(stderr, "error: no package file was specified for --file\n");
return(1);
}
- info = load_pkg(package, pmo_q_info);
+ info = load_pkg(package);
if(info == NULL) {
fprintf(stderr, "error: %s is not a package\n", package);
return(1);
}
if(pmo_q_info) {
+ dump_pkg_full(info);
printf("\n");
} else if(pmo_q_list) {
for(lp = info->files; lp; lp = lp->next) {
@@ -2670,8 +2721,26 @@ PMList* checkdeps(pacdb_t *db, unsigned short op, PMList *targets)
for(j = tp->conflicts; j; j = j->next) {
/* check targets against database */
for(k = pm_packages; k; k = k->next) {
+ int conflict = 0;
pkginfo_t *dp = (pkginfo_t*)k->data;
+ if(!strcmp(dp->name, tp->name)) {
+ /* a package cannot conflict with itself -- that's just not nice */
+ continue;
+ }
if(!strcmp(j->data, dp->name)) {
+ /* dp is listed in tp's conflict list */
+ conflict = 1;
+ } else {
+ /* see if dp provides something in tp's conflict list */
+ PMList *m;
+ for(m = dp->provides; m; m = m->next) {
+ if(!strcmp(m->data, j->data)) {
+ conflict = 1;
+ break;
+ }
+ }
+ }
+ if(conflict) {
MALLOC(miss, sizeof(depmissing_t));
miss->type = CONFLICT;
miss->depend.mod = DEP_ANY;
@@ -2685,14 +2754,32 @@ PMList* checkdeps(pacdb_t *db, unsigned short op, PMList *targets)
}
/* check targets against targets */
for(k = targets; k; k = k->next) {
- pkginfo_t *a = (pkginfo_t*)k->data;
- if(!strcmp(a->name, (char*)j->data)) {
+ int conflict = 0;
+ pkginfo_t *otp = (pkginfo_t*)k->data;
+ if(!strcmp(otp->name, tp->name)) {
+ /* a package cannot conflict with itself -- that's just not nice */
+ continue;
+ }
+ if(!strcmp(otp->name, (char*)j->data)) {
+ /* otp is listed in tp's conflict list */
+ conflict = 1;
+ } else {
+ /* see if otp provides something in tp's conflict list */
+ PMList *m;
+ for(m = otp->provides; m; m = m->next) {
+ if(!strcmp(m->data, j->data)) {
+ conflict = 1;
+ break;
+ }
+ }
+ }
+ if(conflict) {
MALLOC(miss, sizeof(depmissing_t));
miss->type = CONFLICT;
miss->depend.mod = DEP_ANY;
miss->depend.version[0] = '\0';
strncpy(miss->target, tp->name, 256);
- strncpy(miss->depend.name, a->name, 256);
+ strncpy(miss->depend.name, otp->name, 256);
if(!list_isin(baddeps, miss)) {
baddeps = list_add(baddeps, miss);
}
@@ -2703,7 +2790,24 @@ PMList* checkdeps(pacdb_t *db, unsigned short op, PMList *targets)
rewinddir(db->dir);
while((info = db_scan(db, NULL, INFRQ_DESC | INFRQ_DEPENDS)) != NULL) {
for(j = info->conflicts; j; j = j->next) {
+ int conflict = 0;
+ if(!strcmp(info->name, tp->name)) {
+ /* a package cannot conflict with itself -- that's just not nice */
+ continue;
+ }
if(!strcmp((char*)j->data, tp->name)) {
+ conflict = 1;
+ } else {
+ /* see if tp provides something in info's conflict list */
+ PMList *m;
+ for(m = tp->provides; m; m = m->next) {
+ if(!strcmp(m->data, j->data)) {
+ conflict = 1;
+ break;
+ }
+ }
+ }
+ if(conflict) {
MALLOC(miss, sizeof(depmissing_t));
miss->type = CONFLICT;
miss->depend.mod = DEP_ANY;
@@ -3015,7 +3119,7 @@ int parseargs(int op, int argc, char **argv)
case 'h': pmo_help = 1; break;
case 'V': pmo_version = 1; break;
case 'b': strcpy(pmo_dbpath, optarg); break;
- case 'c': pmo_s_clean = 1; pmo_r_cascade = 1; break;
+ case 'c': pmo_s_clean++; pmo_r_cascade = 1; break;
case 'd': pmo_nodeps = 1; break;
case 'e': pmo_q_orphans = 1; break;
case 'f': pmo_force = 1; break;
@@ -3030,7 +3134,7 @@ int parseargs(int op, int argc, char **argv)
perror("bad root path");
return(1);
} break;
- case 's': pmo_s_search = 1; pmo_r_recurse = 1; break;
+ case 's': pmo_s_search = 1; pmo_q_search = 1; pmo_r_recurse = 1; break;
case 'u': pmo_s_upgrade = 1; break;
case 'v': pmo_verbose = 1; break;
case 'w': pmo_s_downloadonly = 1; break;
@@ -3317,20 +3421,21 @@ void usage(int op, char *myname)
printf(" -o, --owns <file> query the package that owns <file>\n");
printf(" -p, --file pacman will query the package file [package] instead of\n");
printf(" looking in the database\n");
+ printf(" -s, --search search locally-installed packages for matching strings\n");
} else if(op == PM_SYNC) {
printf("usage: %s {-S --sync} [options] [package]\n", myname);
printf("options:\n");
- printf(" -c, --clean remove packages from cache directory to free up diskspace\n");
+ printf(" -c, --clean remove old packages from cache directory (use -cc for all)\n");
printf(" -d, --nodeps skip dependency checks\n");
printf(" -f, --force force install, overwrite conflicting files\n");
printf(" -g, --groups view all members of a package group\n");
printf(" -i, --info view package information\n");
printf(" -l, --list list all packages belonging to the specified repository\n");
printf(" -p, --print-uris print out download URIs for each package to be installed\n");
- printf(" -s, --search search sync database for matching strings\n");
+ printf(" -s, --search search remote repositories for matching strings\n");
printf(" -u, --sysupgrade upgrade all packages that are out of date\n");
printf(" -w, --downloadonly download packages, but do not install/upgrade anything\n");
- printf(" -y, --refresh download a fresh package sync database from the server\n");
+ printf(" -y, --refresh download fresh package databases from the server\n");
}
printf(" -v, --verbose be verbose\n");
printf(" -r, --root <path> set an alternate installation root\n");
diff --git a/src/pacman.h b/src/pacman.h
index 3bc7eb3b..bc8e530e 100644
--- a/src/pacman.h
+++ b/src/pacman.h
@@ -22,7 +22,7 @@
#define _PAC_PACMAN_H
#ifndef PACVER
-#define PACVER "2.7.7"
+#define PACVER "2.7.8"
#endif
#ifndef PKGDIR
@@ -33,6 +33,10 @@
#define PACCONF "etc/pacman.conf"
#endif
+#ifndef CACHEDIR
+#define CACHEDIR "var/cache/pacman/pkg"
+#endif
+
/* Operations */
#define PM_MAIN 1
#define PM_ADD 2
diff --git a/src/pacsync.c b/src/pacsync.c
index 0c41f543..d1045a63 100644
--- a/src/pacsync.c
+++ b/src/pacsync.c
@@ -182,6 +182,7 @@ int downloadfiles(PMList *servers, const char *localpath, PMList *files)
if(pmo_xfercommand) {
int ret;
+ int usepart = 0;
char *ptr1, *ptr2;
char origCmd[PATH_MAX];
char parsedCmd[PATH_MAX] = "";
@@ -190,9 +191,22 @@ int downloadfiles(PMList *servers, const char *localpath, PMList *files)
/* build the full download url */
snprintf(url, PATH_MAX, "%s://%s%s%s", server->protocol, server->server,
server->path, fn);
- /* replace all occurrences of %u with the download URL */
+ /* replace all occurrences of %o with fn.part */
strncpy(origCmd, pmo_xfercommand, sizeof(origCmd));
ptr1 = origCmd;
+ while((ptr2 = strstr(ptr1, "%o"))) {
+ usepart = 1;
+ ptr2[0] = '\0';
+ strcat(parsedCmd, ptr1);
+ strcat(parsedCmd, fn);
+ strcat(parsedCmd, ".part");
+ ptr1 = ptr2 + 2;
+ }
+ strcat(parsedCmd, ptr1);
+ /* replace all occurrences of %u with the download URL */
+ strncpy(origCmd, parsedCmd, sizeof(origCmd));
+ parsedCmd[0] = '\0';
+ ptr1 = origCmd;
while((ptr2 = strstr(ptr1, "%u"))) {
ptr2[0] = '\0';
strcat(parsedCmd, ptr1);
@@ -214,11 +228,16 @@ int downloadfiles(PMList *servers, const char *localpath, PMList *files)
return(1);
} else if(ret != 0) {
/* download failed */
- vprint("XferCommand command returned non-zero status code (%d)\n",
- WEXITSTATUS(ret));
+ vprint("XferCommand command returned non-zero status code (%d)\n", ret);
} else {
/* download was successful */
complete = list_add(complete, fn);
+ if(usepart) {
+ char fnpart[PATH_MAX];
+ /* rename "output.part" file to "output" file */
+ snprintf(fnpart, PATH_MAX, "%s.part", fn);
+ rename(fnpart, fn);
+ }
}
chdir(cwd);
} else {
@@ -337,7 +356,7 @@ int downloadfiles(PMList *servers, const char *localpath, PMList *files)
for(j = strlen(out); j < maxcols-64; j++) {
printf(" ");
}
- fputs("] 100% | LOCAL |", stdout);
+ fputs("] 100% LOCAL ", stdout);
} else {
log_progress(control, fsz-offset, &fsz);
}
@@ -351,9 +370,9 @@ int downloadfiles(PMList *servers, const char *localpath, PMList *files)
}
}
if(!pmo_xfercommand) {
- if(!strcmp(server->protocol, "ftp")) {
+ if(!strcmp(server->protocol, "ftp") && !pmo_proxyhost) {
FtpQuit(control);
- } else if(!strcmp(server->protocol, "http")) {
+ } else if(!strcmp(server->protocol, "http") || pmo_proxyhost) {
HttpQuit(control);
}
}
@@ -408,9 +427,9 @@ static int log_progress(netbuf *ctl, int xfered, void *arg)
(i < cur) ? printf("#") : printf(" ");
}
if(rate > 1000) {
- printf("] %3d%%| %6dK| %6.0fK/s| %02d:%02d:%02d\r", pct, ((xfered+offset) / 1024), rate, eta_h, eta_m, eta_s);
+ printf("] %3d%% %6dK %6.0fK/s %02d:%02d:%02d\r", pct, ((xfered+offset) / 1024), rate, eta_h, eta_m, eta_s);
} else {
- printf("] %3d%%| %6dK| %6.1fK/s| %02d:%02d:%02d\r", pct, ((xfered+offset) / 1024), rate, eta_h, eta_m, eta_s);
+ printf("] %3d%% %6dK %6.1fK/s %02d:%02d:%02d\r", pct, ((xfered+offset) / 1024), rate, eta_h, eta_m, eta_s);
}
fflush(stdout);
return(1);