Imported from pacman-2.9.tar.gz

This commit is contained in:
Judd Vinet 2004-09-18 18:37:34 +00:00
parent afc0d9a3c4
commit 4ffc53b339
16 changed files with 354 additions and 227 deletions

View file

@ -1,5 +1,19 @@
VERSION DESCRIPTION VERSION DESCRIPTION
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
2.9 - Improved -Rs functionality -- pacman now tracks why a package
is installed: explicitly, or as a dependency for another
package. -Rs will only remove dependencies that were not
explicitly installed.
- Added compressed package size to sync DBs -- shows the total
size of packages before downloading
- Patch from Tommi Rantala:
- Allow --info and --list together in queries
- Patch from Kevin Piche:
- Use list_add_sorted() with -Sg
- Patch from Hegedus Marton Csaba:
- Better manpage compression
- Added checks for additional hyphens in package versions
- mktemp was failing if %pmo_root%/tmp was missing -- fixed
2.8.4 - Added updatesync script from Jason Chu 2.8.4 - Added updatesync script from Jason Chu
- Changed the pacman binary to be dynamically linked - Changed the pacman binary to be dynamically linked
- Included a pacman.static binary as well - Included a pacman.static binary as well

View file

@ -34,7 +34,7 @@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
INSTALL_DATA = @INSTALL_DATA@ INSTALL_DATA = @INSTALL_DATA@
INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_SCRIPT = @INSTALL_SCRIPT@
PACVER = 2.8.4 PACVER = 2.9
TOPDIR = @srcdir@ TOPDIR = @srcdir@
SRCDIR = $(TOPDIR)/src/ SRCDIR = $(TOPDIR)/src/

View file

@ -1,4 +1,4 @@
.TH pacman 8 "August 3, 2004" "pacman #VERSION#" "" .TH pacman 8 "September 17, 2004" "pacman #VERSION#" ""
.SH NAME .SH NAME
pacman \- package manager utility pacman \- package manager utility
.SH SYNOPSIS .SH SYNOPSIS
@ -53,11 +53,6 @@ Display syntax for the given operation. If no operation was
supplied then the general syntax is shown. supplied then the general syntax is shown.
.SH OPTIONS .SH OPTIONS
.TP .TP
.B "\-c, \-\-cascade"
(only used with \fB--remove\fP)
Remove all target packages, as well as all packages that depend on one
or more target packages. This operation is recursive.
.TP
.B "\-d, \-\-nodeps" .B "\-d, \-\-nodeps"
Skips all dependency checks. Normally, pacman will always check Skips all dependency checks. Normally, pacman will always check
a package's dependency fields to ensure that all dependencies are a package's dependency fields to ensure that all dependencies are
@ -70,17 +65,6 @@ package that is about to be installed contains files that are already
installed, this option will cause all those files to be overwritten. installed, this option will cause all those files to be overwritten.
This option should be used with care, ideally not at all. This option should be used with care, ideally not at all.
.TP .TP
.B "\-k, \-\-keep"
Removes the database entry only. Leaves all files in place.
.TP
.B "\-n, \-\-nosave"
(only used with \fB--remove\fP)
Instructs pacman to ignore file backup designations. Normally, when
a file is about to be \fIremoved\fP from the system the database is first
checked to see if the file should be renamed to a .pacsave extension. If
\fB--nosave\fP is used, these designations are ignored and the files are
removed.
.TP
.B "\-r, \-\-root <path>" .B "\-r, \-\-root <path>"
Specify alternative installation root (default is "/"). This Specify alternative installation root (default is "/"). This
should \fInot\fP be used as a way to install software into should \fInot\fP be used as a way to install software into
@ -90,12 +74,6 @@ which is "owned" by another system. By using this option you not only
specify where the software should be installed, but you also specify where the software should be installed, but you also
specify which package database to use. specify which package database to use.
.TP .TP
.B "\-s, \-\-recursive"
(only used with \fB--remove\fP)
For each target specified, remove it and all its dependencies, provided
they are not required by other packages. This option is analagous to
a backwards --sync operation.
.TP
.B "\-v, \-\-verbose" .B "\-v, \-\-verbose"
Output more status and error messages. Output more status and error messages.
.TP .TP
@ -151,8 +129,34 @@ Retrieve all packages from the server, but do not install/upgrade anything.
Download a fresh copy of the master package list from the ftp server Download a fresh copy of the master package list from the ftp server
defined in \fI/etc/pacman.conf\fP. This should typically be used each defined in \fI/etc/pacman.conf\fP. This should typically be used each
time you use \fB--sysupgrade\fP. time you use \fB--sysupgrade\fP.
.SH REMOVE OPTIONS
.TP
.B "\-c, \-\-cascade"
Remove all target packages, as well as all packages that depend on one
or more target packages. This operation is recursive.
.TP
.B "\-k, \-\-keep"
Removes the database entry only. Leaves all files in place.
.TP
.B "\-n, \-\-nosave"
Instructs pacman to ignore file backup designations. Normally, when
a file is about to be \fIremoved\fP from the system the database is first
checked to see if the file should be renamed to a .pacsave extension. If
\fB--nosave\fP is used, these designations are ignored and the files are
removed.
.TP
.B "\-s, \-\-recursive"
For each target specified, remove it and all its dependencies, provided
that (A) they are not required by other packages; and (B) they were
explicitly installed by the user and not pulled in as a dependency for
other packages. This option is analagous to a backwards --sync operation.
.SH QUERY OPTIONS .SH QUERY OPTIONS
.TP .TP
.B "\-e, \-\-orphans"
List all packages that were explicitly installed (ie, not pulled in
as a dependency by other packages) and are not required by any other
packages.
.TP
.B "\-g, \-\-groups" .B "\-g, \-\-groups"
Display all groups that a specified package is part of. If no package Display all groups that a specified package is part of. If no package
names are provided, all groups and members will be listed. names are provided, all groups and members will be listed.

View file

@ -18,7 +18,7 @@
# #
[options] [options]
LogFile = /var/log/pacman.log LogFile = /var/log/pacman.log
NoUpgrade = etc/passwd etc/group etc/shadow NoUpgrade = etc/passwd etc/group etc/shadow etc/sudoers
NoUpgrade = etc/fstab etc/raidtab etc/ld.so.conf NoUpgrade = etc/fstab etc/raidtab etc/ld.so.conf
NoUpgrade = etc/rc.conf etc/rc.local NoUpgrade = etc/rc.conf etc/rc.local
NoUpgrade = etc/modprobe.conf etc/modules.conf NoUpgrade = etc/modprobe.conf etc/modules.conf

View file

@ -20,7 +20,7 @@
# USA. # USA.
# #
myver='2.8.4' myver='2.9'
usage() { usage() {
echo "gensync $myver" echo "gensync $myver"
@ -45,9 +45,14 @@ usage() {
exit 0 exit 0
} }
die() {
echo "gensync: $*" >&2
rm -rf $gstmpdir
exit 1
}
get_md5checksum() get_md5checksum()
{ {
source $1 || return 1
if [ "$pkgdir" != "" ]; then if [ "$pkgdir" != "" ]; then
pkgfile="$pkgdir/$pkgname-$pkgver-$pkgrel.pkg.tar.gz" pkgfile="$pkgdir/$pkgname-$pkgver-$pkgrel.pkg.tar.gz"
else else
@ -80,6 +85,9 @@ db_write_entry()
echo "%DESC%" >>desc echo "%DESC%" >>desc
echo "$pkgdesc" >>desc echo "$pkgdesc" >>desc
echo "" >>desc echo "" >>desc
echo "%CSIZE%" >>desc
echo "$csize" >>desc
echo "" >>desc
if [ ! -z $pkgmd5sum ]; then if [ ! -z $pkgmd5sum ]; then
echo "%MD5SUM%" >>desc echo "%MD5SUM%" >>desc
echo "$pkgmd5sum" >>desc echo "$pkgmd5sum" >>desc
@ -147,40 +155,30 @@ pkgdir=
if [ "$3" != "" ]; then if [ "$3" != "" ]; then
pkgdir=$3 pkgdir=$3
fi fi
gstmpdir=$(mktemp -dt gensync.XXXXXXXXXX) || exit 1 gstmpdir=$(mktemp -d /tmp/gensync.XXXXXXXXXX) || exit 1
if [ ! -d $rootdir ]; then
echo "gensync: invalid root dir: $rootdir" >&2
rm -rf $gstmpdir
exit 1
fi
[ ! -d $rootdir ] && die "invalid root dir: $rootdir"
echo "gensync: building database entries, generating md5sums..." >&2 echo "gensync: building database entries, generating md5sums..." >&2
cd `dirname $2` cd `dirname $2`
for file in `find $rootdir/* -name PKGBUILD`; do for file in `find $rootdir/* -name PKGBUILD`; do
pkgmd5sum=`get_md5checksum $file $pkgdir` source $file || die "errors parsing $file"
if [ -z $pkgmd5sum ]; then if [ "$pkgdir" != "" ]; then
echo "gensync: error generating checksum for $file" >&2 pkgfile="$pkgdir/$pkgname-$pkgver-$pkgrel.pkg.tar.gz"
rm -rf $gstmpdir else
exit 1 pkgfile="$destdir/$pkgname-$pkgver-$pkgrel.pkg.tar.gz"
fi fi
[ -f $pkgfile ] || die "missing package file: $pkgfile"
csize=`du -b $pkgfile | cut -f1`
pkgmd5sum=`get_md5checksum $pkgfile`
[ -z $pkgmd5sum ] && die "error generating checksum for $pkgfile"
db_write_entry $file db_write_entry $file
if [ $? -gt 0 ]; then [ $? -gt 0 ] && die "error writing entry for $file"
echo "gensync: error writing entry for $file" >&2
rm -rf $gstmpdir
exit 1
fi
done done
echo "gensync: compressing to $destfile..." >&2 echo "gensync: compressing to $destfile..." >&2
cd $gstmpdir cd $gstmpdir
tar c * | gzip -9 >$destfile tar c * | gzip -9 >$destfile
if [ $? -gt 0 ]; then [ $? -gt 0 ] && die "error writing to $destfile"
echo "gensync: error writing to $destfile" >&2
rm -rf $gstmpdir
exit 1
fi
rm -rf $gstmpdir rm -rf $gstmpdir
exit 0 exit 0

View file

@ -20,7 +20,7 @@
# USA. # USA.
# #
myver='2.8.4' myver='2.9'
startdir=`pwd` startdir=`pwd`
PKGDEST=$startdir PKGDEST=$startdir
USE_COLOR="n" USE_COLOR="n"
@ -576,17 +576,17 @@ fi
# compress man pages # compress man pages
msg "Compressing man pages..." msg "Compressing man pages..."
for i in `find pkg/{usr{,/local},opt/*}/man -type f 2>/dev/null`; do find $startdir/pkg/{usr{,/local,/share},opt/*}/man -type f 2>/dev/null | while read i ; do
ext=${i##*.} ext="${i##*.}"
fn=${i##*/} fn="${i##*/}"
if [ "$ext" != "gz" ]; then if [ "$ext" != "gz" -a "$ext" != "bz2" ]; then
# update symlinks to this manpage # update symlinks to this manpage
for ln in `find pkg/{usr{,/local},opt/*}/man -lname "$fn" 2>/dev/null`; do find $startdir/pkg/{usr{,/local,/share},opt/*}/man -lname "$fn" 2> /dev/null | while read ln ; do
rm -f $ln rm -f "$ln"
ln -sf ${fn}.gz ${ln}.gz ln -sf "${fn}.gz" "${ln}.gz"
done done
# compress the original # compress the original
gzip -9 $i gzip -9 "$i"
fi fi
done done

View file

@ -21,7 +21,7 @@
# #
toplevel=`pwd` toplevel=`pwd`
version="2.8.4" version="2.9"
usage() { usage() {
echo "makeworld version $version" echo "makeworld version $version"

View file

@ -21,7 +21,7 @@
# USA. # USA.
# #
myver='2.8.4' myver='2.9'
usage() { usage() {
echo "updatesync $myver" echo "updatesync $myver"
@ -56,7 +56,6 @@ die()
get_md5checksum() get_md5checksum()
{ {
source $1 || return 1
if [ "$pkgdir" != "" ]; then if [ "$pkgdir" != "" ]; then
pkgfile="$pkgdir/$pkgname-$pkgver-$pkgrel.pkg.tar.gz" pkgfile="$pkgdir/$pkgname-$pkgver-$pkgrel.pkg.tar.gz"
else else
@ -89,6 +88,9 @@ db_write_entry()
echo "%DESC%" >>desc echo "%DESC%" >>desc
echo "$pkgdesc" >>desc echo "$pkgdesc" >>desc
echo "" >>desc echo "" >>desc
echo "%CSIZE%" >>desc
echo "$csize" >>desc
echo "" >>desc
if [ ! -z $pkgmd5sum ]; then if [ ! -z $pkgmd5sum ]; then
echo "%MD5SUM%" >>desc echo "%MD5SUM%" >>desc
echo "$pkgmd5sum" >>desc echo "$pkgmd5sum" >>desc
@ -177,7 +179,7 @@ if [ "$action" != "upd" -a "$action" != "del" ]; then
exit 1 exit 1
fi fi
ustmpdir=$(mktemp -dt updatesync.XXXXXXXXXX) || exit 1 ustmpdir=$(mktemp -d /tmp/updatesync.XXXXXXXXXX) || exit 1
cd $ustmpdir cd $ustmpdir
if [ ! -f $pkgdb ]; then if [ ! -f $pkgdb ]; then
@ -202,8 +204,16 @@ if [ "$action" = "upd" ]; then
# INSERT / UPDATE # INSERT / UPDATE
delete_entry $option delete_entry $option
pkgmd5sum=`get_md5checksum $option` source $option || die "errors parsing $option"
[ -z $pkgmd5sum ] && die "error generating checksum for $option" if [ "$pkgdir" != "" ]; then
pkgfile="$pkgdir/$pkgname-$pkgver-$pkgrel.pkg.tar.gz"
else
pkgfile="$destdir/$pkgname-$pkgver-$pkgrel.pkg.tar.gz"
fi
[ -f $pkgfile ] || die "missing package file: $pkgfile"
csize=`du -b $pkgfile | cut -f1`
pkgmd5sum=`get_md5checksum $pkgfile`
[ -z $pkgmd5sum ] && die "error generating checksum for $pkgfile"
echo "updatesync: creating entry for $option" >&2 echo "updatesync: creating entry for $option" >&2
db_write_entry $option || die "error writing entry for $option" db_write_entry $option || die "error writing entry for $option"
else else

View file

@ -225,6 +225,14 @@ pkginfo_t* db_read(pacdb_t *db, struct dirent *ent, unsigned int inforeq)
return(NULL); return(NULL);
} }
trim(info->packager); trim(info->packager);
} else if(!strcmp(line, "%REASON%")) {
char tmp[32];
if(fgets(tmp, sizeof(tmp), fp) == NULL) {
FREEPKG(info);
return(NULL);
}
trim(tmp);
info->reason = (unsigned short)atoi(tmp);
} else if(!strcmp(line, "%SIZE%")) { } else if(!strcmp(line, "%SIZE%")) {
char tmp[32]; char tmp[32];
if(fgets(tmp, sizeof(tmp), fp) == NULL) { if(fgets(tmp, sizeof(tmp), fp) == NULL) {
@ -232,6 +240,19 @@ pkginfo_t* db_read(pacdb_t *db, struct dirent *ent, unsigned int inforeq)
return(NULL); return(NULL);
} }
trim(tmp); trim(tmp);
info->size = (unsigned long)atol(tmp);
} else if(!strcmp(line, "%CSIZE%")) {
/* NOTE: the CSIZE and SIZE fields both share the "size" field
* in the pkginfo_t struct. This can be done b/c CSIZE
* is currently only used in sync databases, and SIZE is
* only used in local databases.
*/
char tmp[32];
if(fgets(tmp, sizeof(tmp), fp) == NULL) {
FREEPKG(info);
return(NULL);
}
trim(tmp);
info->size = atol(tmp); info->size = atol(tmp);
} else if(!strcmp(line, "%REPLACES%")) { } else if(!strcmp(line, "%REPLACES%")) {
/* the REPLACES tag is special -- it only appears in sync repositories, /* the REPLACES tag is special -- it only appears in sync repositories,
@ -387,6 +408,8 @@ int db_write(pacdb_t *db, pkginfo_t *info, unsigned int inforeq)
fprintf(fp, "%s\n\n", info->packager); fprintf(fp, "%s\n\n", info->packager);
fputs("%SIZE%\n", fp); fputs("%SIZE%\n", fp);
fprintf(fp, "%ld\n\n", info->size); fprintf(fp, "%ld\n\n", info->size);
fputs("%REASON%\n", fp);
fprintf(fp, "%d\n\n", info->reason);
fclose(fp); fclose(fp);
} }

View file

@ -102,16 +102,16 @@ int list_isin(PMList *haystack, void *needle)
/* Test for existence of a string in a PMList /* Test for existence of a string in a PMList
*/ */
int is_in(char *needle, PMList *haystack) PMList* is_in(char *needle, PMList *haystack)
{ {
PMList *lp; PMList *lp;
for(lp = haystack; lp; lp = lp->next) { for(lp = haystack; lp; lp = lp->next) {
if(lp->data && !strcmp(lp->data, needle)) { if(lp->data && !strcmp(lp->data, needle)) {
return(1); return(lp);
} }
} }
return(0); return(NULL);
} }
/* List one is extended and returned /* List one is extended and returned
@ -224,6 +224,17 @@ void list_display(const char *title, PMList *list)
} }
/* Helper function for comparing string nodes.
*/
int strlist_cmp(const void *s1, const void *s2)
{
char *str1 = (char *)s1;
char *str2 = (char *)s2;
return(strcmp(str1, str2));
}
/* Add items to a list in sorted order. Use the given /* Add items to a list in sorted order. Use the given
* comparision func to determine order. * comparision func to determine order.
*/ */

View file

@ -40,13 +40,14 @@ void list_free(PMList* list);
PMList* list_add(PMList* list, void* data); PMList* list_add(PMList* list, void* data);
int list_count(PMList* list); int list_count(PMList* list);
int list_isin(PMList *haystack, void *needle); int list_isin(PMList *haystack, void *needle);
int is_in(char *needle, PMList *haystack); PMList* is_in(char *needle, PMList *haystack);
PMList* list_merge(PMList *one, PMList *two); PMList* list_merge(PMList *one, PMList *two);
PMList* list_last(PMList* list); PMList* list_last(PMList* list);
int list_strcmp(const void *s1, const void *s2); int list_strcmp(const void *s1, const void *s2);
PMList *list_sort(PMList *list); PMList *list_sort(PMList *list);
void list_display(const char *title, PMList *list); void list_display(const char *title, PMList *list);
int strlist_cmp(const void *s1, const void *s2);
PMList* list_add_sorted(PMList *list, void *data, cmp_fn sortfunc); PMList* list_add_sorted(PMList *list, void *data, cmp_fn sortfunc);
#endif #endif

View file

@ -250,6 +250,7 @@ pkginfo_t* newpkg()
pkg->size = 0; pkg->size = 0;
pkg->scriptlet = 0; pkg->scriptlet = 0;
pkg->force = 0; pkg->force = 0;
pkg->reason = REASON_EXPLICIT;
pkg->requiredby = NULL; pkg->requiredby = NULL;
pkg->conflicts = NULL; pkg->conflicts = NULL;
pkg->files = NULL; pkg->files = NULL;
@ -340,6 +341,12 @@ void dump_pkg_full(pkginfo_t *info)
printf("Build Date : %s %s\n", info->builddate, strlen(info->builddate) ? "UTC" : ""); printf("Build Date : %s %s\n", info->builddate, strlen(info->builddate) ? "UTC" : "");
printf("Install Date : %s %s\n", info->installdate, strlen(info->installdate) ? "UTC" : ""); printf("Install Date : %s %s\n", info->installdate, strlen(info->installdate) ? "UTC" : "");
printf("Install Script : %s\n", (info->scriptlet ? "Yes" : "No")); printf("Install Script : %s\n", (info->scriptlet ? "Yes" : "No"));
printf("Reason: : ");
switch(info->reason) {
case REASON_EXPLICIT: printf("explicitly installed\n"); break;
case REASON_DEPEND: printf("installed as a dependency for another package\n"); break;
default: printf("unknown\n"); break;
}
pm = list_sort(info->provides); pm = list_sort(info->provides);
list_display("Provides :", pm); list_display("Provides :", pm);
FREELIST(pm); FREELIST(pm);
@ -367,26 +374,27 @@ void dump_pkg_sync(pkginfo_t *info)
return; return;
} }
printf("Name : %s\n", info->name); printf("Name : %s\n", info->name);
printf("Version : %s\n", info->version); printf("Version : %s\n", info->version);
pm = list_sort(info->groups); pm = list_sort(info->groups);
list_display("Groups :", pm); list_display("Groups :", pm);
FREELIST(pm); FREELIST(pm);
pm = list_sort(info->provides); pm = list_sort(info->provides);
list_display("Provides :", pm); list_display("Provides :", pm);
FREELIST(pm); FREELIST(pm);
pm = list_sort(info->depends); pm = list_sort(info->depends);
list_display("Depends On :", pm); list_display("Depends On :", pm);
FREELIST(pm); FREELIST(pm);
pm = list_sort(info->conflicts); pm = list_sort(info->conflicts);
list_display("Conflicts With :", pm); list_display("Conflicts With :", pm);
FREELIST(pm); FREELIST(pm);
pm = list_sort(info->replaces); pm = list_sort(info->replaces);
list_display("Replaces :", pm); list_display("Replaces :", pm);
FREELIST(pm); FREELIST(pm);
printf("Description : "); printf("Size (compressed) : %ld\n", info->size);
indentprint(info->desc, 17); printf("Description : ");
printf("\nMD5 Sum : %s\n", info->md5sum); indentprint(info->desc, 20);
printf("\nMD5 Sum : %s\n", info->md5sum);
} }
int split_pkgname(char *pkgfile, char *name, char *version) int split_pkgname(char *pkgfile, char *name, char *version)

View file

@ -33,6 +33,10 @@
FREELIST(p);\ FREELIST(p);\
} }
/* reasons -- ie, why the package was installed */
#define REASON_EXPLICIT 0 /* explicitly requested by the user */
#define REASON_DEPEND 1 /* installed as a dependency for another package */
/* mods for depend_t.mod */ /* mods for depend_t.mod */
#define DEP_ANY 0 #define DEP_ANY 0
#define DEP_EQ 1 #define DEP_EQ 1
@ -55,6 +59,7 @@ typedef struct __pkginfo_t {
unsigned long size; unsigned long size;
unsigned short scriptlet; unsigned short scriptlet;
unsigned short force; unsigned short force;
unsigned short reason;
PMList *replaces; PMList *replaces;
PMList *groups; PMList *groups;
PMList *files; PMList *files;

View file

@ -235,12 +235,12 @@ int main(int argc, char *argv[])
/* start the requested operation */ /* start the requested operation */
switch(pmo_op) { switch(pmo_op) {
case PM_ADD: ret = pacman_add(db_local, pm_targets); break; case PM_ADD: ret = pacman_add(db_local, pm_targets, NULL); break;
case PM_REMOVE: ret = pacman_remove(db_local, pm_targets); break; case PM_REMOVE: ret = pacman_remove(db_local, pm_targets); break;
case PM_UPGRADE: ret = pacman_upgrade(db_local, pm_targets); break; case PM_UPGRADE: ret = pacman_upgrade(db_local, pm_targets, NULL); break;
case PM_QUERY: ret = pacman_query(db_local, pm_targets); break; case PM_QUERY: ret = pacman_query(db_local, pm_targets); break;
case PM_SYNC: ret = pacman_sync(db_local, pm_targets); break; case PM_SYNC: ret = pacman_sync(db_local, pm_targets); break;
case PM_DEPTEST: ret = pacman_deptest(db_local, pm_targets); break; case PM_DEPTEST: ret = pacman_deptest(db_local, pm_targets); break;
case PM_MAIN: ret = 0; break; case PM_MAIN: ret = 0; break;
default: fprintf(stderr, "error: no operation specified (use -h for help)\n\n"); default: fprintf(stderr, "error: no operation specified (use -h for help)\n\n");
ret = 1; ret = 1;
@ -484,20 +484,19 @@ int pacman_sync(pacdb_t *db, PMList *targets)
} }
} else if(pmo_group) { } else if(pmo_group) {
PMList *pm, *allgroups, *groups; PMList *pm, *allgroups, *groups;
i = NULL; allgroups = NULL;
/* fetch the list of existing groups */ /* fetch the list of existing groups */
for(j = databases; j; j = j->next) { for(j = databases; j; j = j->next) {
dbsync_t *dbs = (dbsync_t*)j->data; dbsync_t *dbs = (dbsync_t*)j->data;
k = find_groups(dbs->db); k = find_groups(dbs->db);
for(pm = k; pm; pm = pm->next) { for(pm = k; pm; pm = pm->next) {
if(!is_in((char *)pm->data, i)) { if(!is_in((char *)pm->data, allgroups)) {
i = list_add(i, strdup((char *)pm->data)); allgroups = list_add_sorted(allgroups, strdup((char *)pm->data),
strlist_cmp);
} }
} }
FREELIST(k); FREELIST(k);
} }
allgroups = list_sort(i);
FREELIST(i);
if(targets) { if(targets) {
groups = NULL; groups = NULL;
for(j = targets; j; j = j->next) { for(j = targets; j; j = j->next) {
@ -705,6 +704,8 @@ int pacman_sync(pacdb_t *db, PMList *targets)
/* re-fetch the package record with dependency info */ /* re-fetch the package record with dependency info */
sync->pkg = db_scan(sync->dbs->db, sync->pkg->name, INFRQ_DESC | INFRQ_DEPENDS); sync->pkg = db_scan(sync->dbs->db, sync->pkg->name, INFRQ_DESC | INFRQ_DEPENDS);
/* copy over the install reason */
sync->pkg->reason = local->reason;
/* add to the targets list */ /* add to the targets list */
found = (find_pkginsync(sync->pkg->name, final) != NULL); found = (find_pkginsync(sync->pkg->name, final) != NULL);
@ -779,6 +780,8 @@ int pacman_sync(pacdb_t *db, PMList *targets)
if(sync->pkg == NULL) { if(sync->pkg == NULL) {
found = 0; found = 0;
} }
/* this package was explicitly requested */
sync->pkg->reason = REASON_EXPLICIT;
} }
} }
} }
@ -1051,6 +1054,8 @@ int pacman_sync(pacdb_t *db, PMList *targets)
if(final && final->data && allgood && !pmo_s_printuris) { if(final && final->data && allgood && !pmo_s_printuris) {
PMList *list = NULL; PMList *list = NULL;
char *str; char *str;
unsigned long totalsize = 0;
double mb;
for(i = rmtargs; i; i = i->next) { for(i = rmtargs; i; i = i->next) {
list = list_add(list, strdup(i->data)); list = list_add(list, strdup(i->data));
} }
@ -1076,12 +1081,14 @@ int pacman_sync(pacdb_t *db, PMList *targets)
MALLOC(str, strlen(s->pkg->name)+strlen(s->pkg->version)+2); MALLOC(str, strlen(s->pkg->name)+strlen(s->pkg->version)+2);
sprintf(str, "%s-%s", s->pkg->name, s->pkg->version); sprintf(str, "%s-%s", s->pkg->name, s->pkg->version);
list = list_add(list, str); list = list_add(list, str);
totalsize += s->pkg->size;
} }
} }
mb = (double)(totalsize / 1048576.0);
printf("\nTargets: "); printf("\nTargets: ");
str = buildstring(list); str = buildstring(list);
indentprint(str, 9); indentprint(str, 9);
printf("\n"); printf("\n\nTotal Package Size: %.1f MB\n", mb);
FREELIST(list); FREELIST(list);
FREE(str); FREE(str);
} }
@ -1178,14 +1185,11 @@ int pacman_sync(pacdb_t *db, PMList *targets)
fflush(stdout); fflush(stdout);
if(stat(ldir, &buf)) { if(stat(ldir, &buf)) {
mode_t oldmask; mode_t oldmask;
char parent[PATH_MAX];
/* no cache directory.... try creating it */ /* no cache directory.... try creating it */
snprintf(parent, PATH_MAX, "%svar/cache/pacman", pmo_root);
logaction(stderr, "warning: no %s cache exists. creating...", ldir); logaction(stderr, "warning: no %s cache exists. creating...", ldir);
oldmask = umask(0000); oldmask = umask(0000);
mkdir(parent, 0755); if(makepath(ldir)) {
if(mkdir(ldir, 0755)) {
/* couldn't mkdir the cache directory, so fall back to /tmp and unlink /* couldn't mkdir the cache directory, so fall back to /tmp and unlink
* the package afterwards. * the package afterwards.
*/ */
@ -1295,6 +1299,7 @@ int pacman_sync(pacdb_t *db, PMList *targets)
} }
if(!pmo_s_downloadonly && allgood) { if(!pmo_s_downloadonly && allgood) {
PMList *dependonly = NULL;
/* remove any conflicting packages (WITHOUT dep checks) */ /* remove any conflicting packages (WITHOUT dep checks) */
if(rmtargs) { if(rmtargs) {
int retcode; int retcode;
@ -1320,6 +1325,9 @@ int pacman_sync(pacdb_t *db, PMList *targets)
MALLOC(str, PATH_MAX); MALLOC(str, PATH_MAX);
snprintf(str, PATH_MAX, "%s/%s-%s.pkg.tar.gz", ldir, sync->pkg->name, sync->pkg->version); snprintf(str, PATH_MAX, "%s/%s-%s.pkg.tar.gz", ldir, sync->pkg->name, sync->pkg->version);
files = list_add(files, str); files = list_add(files, str);
if(sync->pkg->reason == REASON_DEPEND) {
dependonly = list_add(dependonly, strdup(str));
}
} }
for(j = sync->replaces; j; j = j->next) { for(j = sync->replaces; j; j = j->next) {
pkginfo_t *pkg = (pkginfo_t*)j->data; pkginfo_t *pkg = (pkginfo_t*)j->data;
@ -1339,7 +1347,7 @@ int pacman_sync(pacdb_t *db, PMList *targets)
} }
/* install targets */ /* install targets */
if(allgood) { if(allgood) {
allgood = !pacman_upgrade(db, files); allgood = !pacman_upgrade(db, files, dependonly);
} }
/* propagate replaced packages' requiredby fields to their new owners */ /* propagate replaced packages' requiredby fields to their new owners */
if(allgood) { if(allgood) {
@ -1413,7 +1421,7 @@ sync_cleanup:
return(!allgood); return(!allgood);
} }
int pacman_add(pacdb_t *db, PMList *targets) int pacman_add(pacdb_t *db, PMList *targets, PMList *dependonly)
{ {
int i, ret = 0, errors = 0; int i, ret = 0, errors = 0;
TAR *tar = NULL; TAR *tar = NULL;
@ -1435,6 +1443,10 @@ int pacman_add(pacdb_t *db, PMList *targets)
if(targets == NULL) { if(targets == NULL) {
return(0); return(0);
} }
/*
* Check for URL targets and process them
*
*/
for(targ = targets; targ; targ = targ->next) { for(targ = targets; targ; targ = targ->next) {
if(strstr(targ->data, "://")) { if(strstr(targ->data, "://")) {
/* this target looks like an URL. download it and then /* this target looks like an URL. download it and then
@ -1485,6 +1497,10 @@ int pacman_add(pacdb_t *db, PMList *targets)
} }
} }
/*
* Load meta-data from package files
*
*/
printf("loading package data... "); printf("loading package data... ");
fflush(stdout); fflush(stdout);
for(targ = targets; targ; targ = targ->next) { for(targ = targets; targ; targ = targ->next) {
@ -1494,6 +1510,12 @@ int pacman_add(pacdb_t *db, PMList *targets)
if(info == NULL) { if(info == NULL) {
return(1); return(1);
} }
/* no additional hyphens in version strings */
if(strchr(info->version, '-') != strrchr(info->version, '-')) {
fprintf(stderr, "\nerror: package \"%s\" has more than one hyphen in its version (%s)\n",
info->name, info->version);
return(1);
}
if(pmo_freshen) { if(pmo_freshen) {
/* only upgrade/install this package if it is already installed and at a lesser version */ /* only upgrade/install this package if it is already installed and at a lesser version */
pkginfo_t *dummy = db_scan(db, info->name, INFRQ_DESC); pkginfo_t *dummy = db_scan(db, info->name, INFRQ_DESC);
@ -1525,6 +1547,11 @@ int pacman_add(pacdb_t *db, PMList *targets)
} }
printf("done.\n"); printf("done.\n");
/*
* Check dependencies
*
*/
/* No need to check deps if pacman_add was called during a sync: /* No need to check deps if pacman_add was called during a sync:
* it is already done in pacman_sync. */ * it is already done in pacman_sync. */
if(!pmo_nodeps && pmo_op != PM_SYNC) { if(!pmo_nodeps && pmo_op != PM_SYNC) {
@ -1636,6 +1663,10 @@ int pacman_add(pacdb_t *db, PMList *targets)
alltargs = lp; alltargs = lp;
} }
/*
* Check for file conflicts
*
*/
if(!pmo_force) { if(!pmo_force) {
printf("checking for file conflicts... "); printf("checking for file conflicts... ");
fflush(stdout); fflush(stdout);
@ -1657,6 +1688,10 @@ int pacman_add(pacdb_t *db, PMList *targets)
/* this can get modified in the next for loop, so we reset it on each iteration */ /* this can get modified in the next for loop, so we reset it on each iteration */
real_pmo_upgrade = pmo_upgrade; real_pmo_upgrade = pmo_upgrade;
/*
* Install packages
*
*/
for(targ = alltargs, file = filenames; targ && file; targ = targ->next, file = file->next) { for(targ = alltargs, file = filenames; targ && file; targ = targ->next, file = file->next) {
pkginfo_t* oldpkg = NULL; pkginfo_t* oldpkg = NULL;
info = (pkginfo_t*)targ->data; info = (pkginfo_t*)targ->data;
@ -1682,33 +1717,13 @@ int pacman_add(pacdb_t *db, PMList *targets)
/* pre_upgrade scriptlet */ /* pre_upgrade scriptlet */
if(info->scriptlet) { if(info->scriptlet) {
char tmpdir[PATH_MAX]; runscriptlet(file->data, "pre_upgrade", info->version, oldpkg ? oldpkg->version : NULL);
char *rtmpdir;
snprintf(tmpdir, PATH_MAX, "%stmp/pacman-XXXXXX", pmo_root);
if(mkdtemp(tmpdir) == NULL) {
perror("error creating temp directory");
return(1);
}
/* chop off the pmo_root so we can find the tmpdir in the chroot */
rtmpdir = tmpdir + strlen(pmo_root) - 1;
unpack(file->data, tmpdir, ".INSTALL");
/* run the post-install script if it exists */
snprintf(pm_install, PATH_MAX, "%s/.INSTALL", tmpdir);
if(grep(pm_install, "pre_upgrade")) {
char cmdline[PATH_MAX+1];
snprintf(pm_install, PATH_MAX, "%s/.INSTALL", rtmpdir);
vprint("Executing pre-upgrade script...\n");
snprintf(cmdline, PATH_MAX, "echo \"umask 0022; source %s pre_upgrade %s %s\" | chroot %s /bin/sh",
pm_install, info->version, (oldpkg ? oldpkg->version : ""), pmo_root);
system(cmdline);
}
if(rmrf(tmpdir)) {
fprintf(stderr, "warning: could not remove tmpdir %s\n", tmpdir);
}
} }
if(oldpkg) { if(oldpkg) {
PMList* tmp = list_add(NULL, strdup(info->name)); PMList* tmp = list_add(NULL, strdup(info->name));
/* copy over the install reason */
info->reason = oldpkg->reason;
vprint("removing old package first...\n"); vprint("removing old package first...\n");
retcode = pacman_remove(db, tmp); retcode = pacman_remove(db, tmp);
FREELIST(tmp); FREELIST(tmp);
@ -1727,34 +1742,13 @@ int pacman_add(pacdb_t *db, PMList *targets)
pmo_upgrade = 0; pmo_upgrade = 0;
} }
} }
if(!pmo_upgrade) { if(!pmo_upgrade) {
printf("installing %s... ", info->name); printf("installing %s... ", info->name);
neednl = 1; neednl = 1;
/* pre_install scriptlet */ /* pre_install scriptlet */
if(info->scriptlet) { if(info->scriptlet) {
char tmpdir[PATH_MAX]; runscriptlet(file->data, "pre_install", info->version, NULL);
char *rtmpdir;
snprintf(tmpdir, PATH_MAX, "%stmp/pacman-XXXXXX", pmo_root);
if(mkdtemp(tmpdir) == NULL) {
perror("error creating temp directory");
return(1);
}
/* chop off the pmo_root so we can find the tmpdir in the chroot */
rtmpdir = tmpdir + strlen(pmo_root) - 1;
unpack(file->data, tmpdir, ".INSTALL");
/* run the post-install script if it exists */
snprintf(pm_install, PATH_MAX, "%s/.INSTALL", tmpdir);
if(grep(pm_install, "pre_install")) {
char cmdline[PATH_MAX+1];
snprintf(pm_install, PATH_MAX, "%s/.INSTALL", rtmpdir);
vprint("Executing pre-install script...\n");
snprintf(cmdline, PATH_MAX, "echo \"umask 0022; source %s pre_install %s\" | chroot %s /bin/sh",
pm_install, info->version, pmo_root);
system(cmdline);
}
if(rmrf(tmpdir)) {
fprintf(stderr, "warning: could not remove tmpdir %s\n", tmpdir);
}
} }
} }
fflush(stdout); fflush(stdout);
@ -1792,7 +1786,7 @@ int pacman_add(pacdb_t *db, PMList *targets)
notouch = 1; notouch = 1;
} else { } else {
if(!pmo_upgrade || oldpkg == NULL) { if(!pmo_upgrade || oldpkg == NULL) {
nb = is_in(pathname, info->backup); nb = is_in(pathname, info->backup) ? 1 : 0;
} else { } else {
/* op == PM_UPGRADE */ /* op == PM_UPGRADE */
md5_orig = needbackup(pathname, oldpkg->backup); md5_orig = needbackup(pathname, oldpkg->backup);
@ -1976,6 +1970,13 @@ int pacman_add(pacdb_t *db, PMList *targets)
} }
vprint("Updating database..."); vprint("Updating database...");
/* Figure out whether this package was installed explicitly by the user
* or installed as a dependency for another package
*/
info->reason = REASON_EXPLICIT;
if(is_in(file->data, dependonly)) {
info->reason = REASON_DEPEND;
}
/* make an install date (in UTC) */ /* make an install date (in UTC) */
strncpy(info->installdate, asctime(gmtime(&t)), sizeof(info->installdate)); strncpy(info->installdate, asctime(gmtime(&t)), sizeof(info->installdate));
if(db_write(db, info, INFRQ_ALL)) { if(db_write(db, info, INFRQ_ALL)) {
@ -2019,16 +2020,12 @@ int pacman_add(pacdb_t *db, PMList *targets)
} }
printf("done.\n"); fflush(stdout); printf("done.\n"); fflush(stdout);
/* run the post-install script if it exists */ /* run the post-install/upgrade 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); 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) && (grep(pm_install, "post_install") || grep(pm_install, "post_upgrade"))) { if(pmo_upgrade) {
char cmdline[PATH_MAX+1]; runscriptlet(pm_install, "post_upgrade", info->version, oldpkg ? oldpkg->version : NULL);
snprintf(pm_install, PATH_MAX, "%s/%s/%s-%s/install", pmo_dbpath, db->treename, info->name, info->version); } else {
vprint("Executing post-install script...\n"); runscriptlet(pm_install, "post_install", info->version, NULL);
snprintf(cmdline, PATH_MAX, "echo \"umask 0022; source %s post_%s %s %s\" | chroot %s /bin/sh",
pm_install, (pmo_upgrade ? "upgrade" : "install"), info->version,
((pmo_upgrade && oldpkg) ? oldpkg->version : ""), pmo_root);
system(cmdline);
} }
} }
@ -2170,16 +2167,9 @@ int pacman_remove(pacdb_t *db, PMList *targets)
printf("removing %s... ", info->name); printf("removing %s... ", info->name);
neednl = 1; neednl = 1;
fflush(stdout); fflush(stdout);
/* run the pre-remove script if it exists */ /* run the pre-remove scriptlet if it exists */
snprintf(pm_install, PATH_MAX, "%s%s/%s/%s-%s/install", pmo_root, pmo_dbpath, db->treename, info->name, info->version); 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) && grep(pm_install, "pre_remove")) { runscriptlet(pm_install, "pre_remove", info->version, NULL);
vprint("Executing pre-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, "echo \"umask 0022; source %s pre_remove %s\" | chroot %s /bin/sh",
pm_install, info->version, pmo_root);
system(line);
}
} }
if(!pmo_r_dbonly) { if(!pmo_r_dbonly) {
@ -2236,14 +2226,7 @@ int pacman_remove(pacdb_t *db, PMList *targets)
if(!pmo_upgrade) { if(!pmo_upgrade) {
/* run the post-remove script if it exists */ /* 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); 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) && grep(pm_install, "post_remove")) { runscriptlet(pm_install, "post_remove", info->version, NULL);
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, "echo \"umask 0022; source %s post_remove %s\" | chroot %s /bin/sh",
pm_install, info->version, pmo_root);
system(line);
}
} }
/* remove the package from the database */ /* remove the package from the database */
@ -2398,11 +2381,13 @@ int pacman_query(pacdb_t *db, PMList *targets)
if(pmo_q_info) { if(pmo_q_info) {
dump_pkg_full(info); dump_pkg_full(info);
printf("\n"); printf("\n");
} else if(pmo_q_list) { }
if(pmo_q_list) {
for(lp = info->files; lp; lp = lp->next) { for(lp = info->files; lp; lp = lp->next) {
printf("%s %s\n", info->name, (char*)lp->data); printf("%s %s\n", info->name, (char*)lp->data);
} }
} else { }
if (!pmo_q_info && !pmo_q_list) {
printf("%s %s\n", info->name, info->version); printf("%s %s\n", info->name, info->version);
} }
FREEPKG(info); FREEPKG(info);
@ -2444,23 +2429,21 @@ int pacman_query(pacdb_t *db, PMList *targets)
/* no target */ /* no target */
for(lp = pm_packages; lp; lp = lp->next) { for(lp = pm_packages; lp; lp = lp->next) {
pkginfo_t *tmpp = (pkginfo_t*)lp->data; pkginfo_t *tmpp = (pkginfo_t*)lp->data;
if(pmo_q_list) { if(pmo_q_list || pmo_q_orphans) {
info = db_scan(db, tmpp->name, INFRQ_DESC | INFRQ_FILES); info = db_scan(db, tmpp->name, INFRQ_ALL);
if(info == NULL) { if(info == NULL) {
/* something weird happened */ /* something weird happened */
return(1); return(1);
} }
for(q = info->files; q; q = q->next) { if(pmo_q_list) {
printf("%s %s%s\n", info->name, pmo_root, (char*)q->data); for(q = info->files; q; q = q->next) {
printf("%s %s%s\n", info->name, pmo_root, (char*)q->data);
}
} }
FREEPKG(info); if(pmo_q_orphans) {
} else if(pmo_q_orphans) { if(info->requiredby == NULL && info->reason == REASON_EXPLICIT) {
info = db_scan(db, tmpp->name, INFRQ_DESC | INFRQ_DEPENDS); printf("%s %s\n", tmpp->name, tmpp->version);
if(info == NULL) { }
return(1);
}
if(info->requiredby == NULL) {
printf("%s %s\n", tmpp->name, tmpp->version);
} }
FREEPKG(info); FREEPKG(info);
} else { } else {
@ -2469,55 +2452,53 @@ int pacman_query(pacdb_t *db, PMList *targets)
} }
} else { } else {
/* find a target */ /* find a target */
if(pmo_q_info) { if(pmo_q_info || pmo_q_list) {
info = db_scan(db, package, INFRQ_ALL); info = db_scan(db, package, INFRQ_ALL);
if(info == NULL) { if(info == NULL) {
fprintf(stderr, "Package \"%s\" was not found.\n", package); fprintf(stderr, "Package \"%s\" was not found.\n", package);
return(2); return(2);
} }
dump_pkg_full(info); if(pmo_q_info) {
if(pmo_q_info > 1 && info->backup) { dump_pkg_full(info);
/* extra info */ if(pmo_q_info > 1 && info->backup) {
printf("\n"); /* extra info */
for(lp = info->backup; lp; lp = lp->next) { printf("\n");
struct stat buf; for(lp = info->backup; lp; lp = lp->next) {
char path[PATH_MAX]; struct stat buf;
char *md5sum; char path[PATH_MAX];
char *str = strdup(lp->data); char *md5sum;
char *ptr = index(str, '\t'); char *str = strdup(lp->data);
if(ptr == NULL) { char *ptr = index(str, '\t');
FREE(str); if(ptr == NULL) {
continue; FREE(str);
}
*ptr = '\0';
ptr++;
snprintf(path, PATH_MAX-1, "%s%s", pmo_root, str);
if(!stat(path, &buf)) {
md5sum = MDFile(path);
if(md5sum == NULL) {
fprintf(stderr, "error calculating md5sum for %s\n", path);
continue; continue;
} }
if(strcmp(md5sum, ptr)) { *ptr = '\0';
printf("MODIFIED\t%s\n", path); ptr++;
snprintf(path, PATH_MAX-1, "%s%s", pmo_root, str);
if(!stat(path, &buf)) {
md5sum = MDFile(path);
if(md5sum == NULL) {
fprintf(stderr, "error calculating md5sum for %s\n", path);
continue;
}
if(strcmp(md5sum, ptr)) {
printf("MODIFIED\t%s\n", path);
} else {
printf("NOT MODIFIED\t%s\n", path);
}
} else { } else {
printf("NOT MODIFIED\t%s\n", path); printf("MISSING\t\t%s\n", path);
} }
} else { FREE(str);
printf("MISSING\t\t%s\n", path);
} }
FREE(str);
} }
printf("\n");
} }
printf("\n"); if(pmo_q_list) {
} else if(pmo_q_list) { for(lp = info->files; lp; lp = lp->next) {
info = db_scan(db, package, INFRQ_DESC | INFRQ_FILES); printf("%s %s%s\n", info->name, pmo_root, (char*)lp->data);
if(info == NULL) { }
fprintf(stderr, "Package \"%s\" was not found.\n", package);
return(2);
}
for(lp = info->files; lp; lp = lp->next) {
printf("%s %s%s\n", info->name, pmo_root, (char*)lp->data);
} }
} else if(pmo_q_orphans) { } else if(pmo_q_orphans) {
info = db_scan(db, package, INFRQ_DESC | INFRQ_DEPENDS); info = db_scan(db, package, INFRQ_DESC | INFRQ_DEPENDS);
@ -2543,12 +2524,12 @@ int pacman_query(pacdb_t *db, PMList *targets)
return(0); return(0);
} }
int pacman_upgrade(pacdb_t *db, PMList *targets) int pacman_upgrade(pacdb_t *db, PMList *targets, PMList *dependonly)
{ {
/* this is basically just a remove-then-add process. pacman_add() will */ /* this is basically just a remove-then-add process. pacman_add() will */
/* handle it */ /* handle it */
pmo_upgrade = 1; pmo_upgrade = 1;
return(pacman_add(db, targets)); return(pacman_add(db, targets, dependonly));
} }
/* Re-order a list of target packages with respect to their dependencies. /* Re-order a list of target packages with respect to their dependencies.
@ -2630,6 +2611,10 @@ PMList* sortbydeps(PMList *targets)
* target list, as well as all their un-needed dependencies. By un-needed, * target list, as well as all their un-needed dependencies. By un-needed,
* I mean dependencies that are *only* required for packages in the target * I mean dependencies that are *only* required for packages in the target
* list, so they can be safely removed. This function is recursive. * list, so they can be safely removed. This function is recursive.
*
* NOTE: as of version 2.9, this will only remove packages that were
* not explicitly installed (ie, reason == REASON_DEPEND)
*
*/ */
PMList* removedeps(pacdb_t *db, PMList *targs) PMList* removedeps(pacdb_t *db, PMList *targs)
{ {
@ -2663,6 +2648,11 @@ PMList* removedeps(pacdb_t *db, PMList *targs)
if(is_pkgin(dep, targs)) { if(is_pkgin(dep, targs)) {
continue; continue;
} }
/* see if it was explicitly installed */
if(dep->reason == REASON_EXPLICIT) {
vprint("excluding %s -- explicitly installed\n", dep->name);
needed = 1;
}
/* see if other packages need it */ /* see if other packages need it */
for(k = dep->requiredby; k && !needed; k = k->next) { for(k = dep->requiredby; k && !needed; k = k->next) {
pkginfo_t *dummy; pkginfo_t *dummy;
@ -2726,6 +2716,7 @@ int resolvedeps(pacdb_t *local, PMList *databases, syncpkg_t *syncpkg, PMList *l
found = 1; found = 1;
/* re-fetch the package record with dependency info */ /* re-fetch the package record with dependency info */
sync->pkg = db_scan(dbs->db, pkg->name, INFRQ_DESC | INFRQ_DEPENDS); sync->pkg = db_scan(dbs->db, pkg->name, INFRQ_DESC | INFRQ_DEPENDS);
sync->pkg->reason = REASON_DEPEND;
sync->dbs = dbs; sync->dbs = dbs;
} }
} }
@ -2739,6 +2730,7 @@ int resolvedeps(pacdb_t *local, PMList *databases, syncpkg_t *syncpkg, PMList *l
found = 1; found = 1;
/* re-fetch the package record with dependency info */ /* re-fetch the package record with dependency info */
sync->pkg = db_scan(dbs->db, provides->data, INFRQ_DESC | INFRQ_DEPENDS); sync->pkg = db_scan(dbs->db, provides->data, INFRQ_DESC | INFRQ_DEPENDS);
sync->pkg->reason = REASON_DEPEND;
sync->dbs = dbs; sync->dbs = dbs;
} }
list_free(provides); list_free(provides);
@ -3222,6 +3214,63 @@ char* needbackup(char* file, PMList *backup)
return(NULL); return(NULL);
} }
/* Executes a scriptlet.
*/
int runscriptlet(char *installfn, char *script, char *ver, char *oldver)
{
char scriptfn[PATH_MAX];
char cmdline[PATH_MAX];
char tmpdir[PATH_MAX] = "";
char *scriptpath;
struct stat buf;
if(stat(installfn, &buf)) {
/* not found */
return(0);
}
if(!strcmp(script, "pre_upgrade") || !strcmp(script, "pre_install")) {
snprintf(tmpdir, PATH_MAX, "%stmp/", pmo_root);
if(stat(tmpdir, &buf)) {
makepath(tmpdir);
}
snprintf(tmpdir, PATH_MAX, "%stmp/pacman-XXXXXX", pmo_root);
if(mkdtemp(tmpdir) == NULL) {
perror("error creating temp directory");
return(1);
}
unpack(installfn, tmpdir, ".INSTALL");
snprintf(scriptfn, PATH_MAX, "%s/.INSTALL", tmpdir);
/* chop off the pmo_root so we can find the tmpdir in the chroot */
scriptpath = scriptfn + strlen(pmo_root) - 1;
} else {
strncpy(scriptfn, installfn, PATH_MAX-1);
/* chop off the pmo_root so we can find the tmpdir in the chroot */
scriptpath = scriptfn + strlen(pmo_root) - 1;
}
if(!grep(scriptfn, script)) {
/* script not found in scriptlet file */
return(0);
}
vprint("Executing %s script...\n", script);
if(oldver) {
snprintf(cmdline, PATH_MAX, "echo \"umask 0022; source %s %s %s %s\" | chroot %s /bin/sh",
scriptpath, script, ver, oldver, pmo_root);
} else {
snprintf(cmdline, PATH_MAX, "echo \"umask 0022; source %s %s %s\" | chroot %s /bin/sh",
scriptpath, script, ver, pmo_root);
}
vprint("%s\n", cmdline);
system(cmdline);
if(strlen(tmpdir) && rmrf(tmpdir)) {
fprintf(stderr, "warning: could not remove tmpdir %s\n", tmpdir);
}
return(0);
}
/* Parse command-line arguments for each operation /* Parse command-line arguments for each operation
* op: the operation code requested * op: the operation code requested
* argc: argc * argc: argc
@ -3615,8 +3664,10 @@ void usage(int op, char *myname)
} else if(op == PM_QUERY) { } else if(op == PM_QUERY) {
printf("usage: %s {-Q --query} [options] [package]\n", myname); printf("usage: %s {-Q --query} [options] [package]\n", myname);
printf("options:\n"); printf("options:\n");
printf(" -i, --info view package information (use -ii for more)\n"); printf(" -e, --orphans list all packages that were explicitly installed\n");
printf(" and are not required by any other packages\n");
printf(" -g, --groups view all members of a package group\n"); printf(" -g, --groups view all members of a package group\n");
printf(" -i, --info view package information (use -ii for more)\n");
printf(" -l, --list list the contents of the queried package\n"); printf(" -l, --list list the contents of the queried package\n");
printf(" -o, --owns <file> query the package that owns <file>\n"); printf(" -o, --owns <file> query the package that owns <file>\n");
printf(" -p, --file pacman will query the package file [package] instead of\n"); printf(" -p, --file pacman will query the package file [package] instead of\n");

View file

@ -22,7 +22,7 @@
#define _PAC_PACMAN_H #define _PAC_PACMAN_H
#ifndef PACVER #ifndef PACVER
#define PACVER "2.8.4" #define PACVER "2.9"
#endif #endif
#ifndef PKGDIR #ifndef PKGDIR
@ -48,9 +48,9 @@
#define min(X, Y) ((X) < (Y) ? (X) : (Y)) #define min(X, Y) ((X) < (Y) ? (X) : (Y))
int pacman_add(pacdb_t *db, PMList *targets); int pacman_add(pacdb_t *db, PMList *targets, PMList *dependonly);
int pacman_remove(pacdb_t *db, PMList *targets); int pacman_remove(pacdb_t *db, PMList *targets);
int pacman_upgrade(pacdb_t *db, PMList *targets); int pacman_upgrade(pacdb_t *db, PMList *targets, PMList *dependonly);
int pacman_query(pacdb_t *db, PMList *targets); int pacman_query(pacdb_t *db, PMList *targets);
int pacman_sync(pacdb_t *db, PMList *targets); int pacman_sync(pacdb_t *db, PMList *targets);
int pacman_deptest(pacdb_t *db, PMList *targets); int pacman_deptest(pacdb_t *db, PMList *targets);
@ -62,6 +62,7 @@ int resolvedeps(pacdb_t *local, PMList *databases, syncpkg_t *sync, PMList *list
int splitdep(char *depstr, depend_t *depend); int splitdep(char *depstr, depend_t *depend);
char* needbackup(char *file, PMList *backup); char* needbackup(char *file, PMList *backup);
int runscriptlet(char *installfn, char *script, char *ver, char *oldver);
int parseargs(int op, int argc, char **argv); int parseargs(int op, int argc, char **argv);
int parseconfig(char *configfile); int parseconfig(char *configfile);

View file

@ -147,6 +147,7 @@ int makepath(char *path)
if(stat(full, &buf)) { if(stat(full, &buf)) {
if(mkdir(full, 0755)) { if(mkdir(full, 0755)) {
free(orig); free(orig);
umask(oldmask);
return(1); return(1);
} }
} }