Imported from pacman-2.8.1.tar.gz

This commit is contained in:
Judd Vinet 2004-07-17 01:55:28 +00:00
parent f6661379c6
commit 75ace390f7
14 changed files with 285 additions and 38 deletions

View file

@ -1,5 +1,18 @@
VERSION DESCRIPTION
-----------------------------------------------------------------------------
2.8.1 - Added a HoldPkg option in pacman.conf, for the more
exploratory users who run things like "pacman -R pacman". It
will ask for confirmation before removing any packages listed
in the HoldPkg list
- Added a --noconfirm switch for use with script automation
- Modified dependency resolution to prefer packages explicitly
requested on the cmdline instead of those pulled in by
resolvedeps(). Example, if neither "xorg" nor "xfree86" is
installed and "blackbox xfree86" is requested, "xfree86" will
be used instead of "xorg"
- Added patch from Jason Chu:
- Smarter file-conflict checking with symlinked paths and
with files that move from one package to another
2.8 - Bugfixes:
- #861: file:/// urls not handled properly with XferCommand
- #1003: set umask before scriptlet calls

View file

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

View file

@ -1,4 +1,4 @@
.TH pacman 8 "July 2, 2004" "pacman #VERSION#" ""
.TH pacman 8 "July 16, 2004" "pacman #VERSION#" ""
.SH NAME
pacman \- package manager utility
.SH SYNOPSIS
@ -98,6 +98,10 @@ a backwards --sync operation.
.TP
.B "\-v, \-\-verbose"
Output more status and error messages.
.TP
.B "\-\-noconfirm"
Bypass any and all "Are you sure?" messages. It's not a good to do this
unless you want to run pacman from a script.
.SH SYNC OPTIONS
.TP
.B "\-c, \-\-clean"
@ -227,6 +231,10 @@ Server = file:///home/pkgs
Overrides the default location of the toplevel database directory. The default is
\fIvar/lib/pacman\fP.
.TP
.B "HoldPkg = <package> [package] ..."
If a user tries to \fB--remove\fP a package that's listed in HoldPkg, pacman
will ask for confirmation before proceeding.
.TP
.B "IgnorePkg = <package> [package] ..."
Instructs pacman to ignore any upgrades for this package when performing a
\fB--sysupgrade\fP.

View file

@ -19,10 +19,11 @@
[options]
LogFile = /var/log/pacman.log
NoUpgrade = etc/passwd etc/group etc/shadow
NoUpgrade = etc/fstab etc/raidtab
NoUpgrade = etc/fstab etc/raidtab etc/ld.so.conf
NoUpgrade = etc/rc.conf etc/rc.local
NoUpgrade = etc/modprobe.conf etc/modules.conf
NoUpgrade = etc/lilo.conf boot/grub/menu.lst
HoldPkg = pacman glibc
#XferCommand = /usr/bin/wget --passive-ftp -c -O %o %u
#
@ -33,6 +34,7 @@ Server = ftp://ftp.archlinux.org/current/os/i686
Server = ftp://ftp.oit.unc.edu/pub/Linux/distributions/archlinux/current/os/i686
Server = ftp://ftp.archlinux.de/pub/archlinux/current/os/i686
Server = ftp://ftp.ibiblio.org/pub/linux/distributions/archlinux/current/os/i686
Server = http://archlinux.antesis.org/current/os/i686
Server = ftp://ftp.mpi-sb.mpg.de/pub/linux/mirror/ftp.ibiblio.org/pub/Linux/distributions/archlinux/current/os/i686
Server = ftp://ftp.tu-chemnitz.de/pub/linux/sunsite.unc-mirror/distributions/archlinux/current/os/i686
Server = ftp://ftp.parrswood.net/Mirrors/ftp.archlinux.org/current/os/i686
@ -49,6 +51,7 @@ Server = ftp://ftp.rez-gif.supelec.fr/pub/Linux/distrib/archlinux/current/os/i68
Server = ftp://ftp.oit.unc.edu/pub/Linux/distributions/archlinux/extra/os/i686
Server = ftp://ftp.archlinux.de/pub/archlinux/extra/os/i686
Server = ftp://ftp.ibiblio.org/pub/linux/distributions/archlinux/extra/os/i686
Server = http://archlinux.antesis.org/extra/os/i686
Server = ftp://ftp.mpi-sb.mpg.de/pub/linux/mirror/ftp.ibiblio.org/pub/Linux/distributions/archlinux/extra/os/i686
Server = ftp://ftp.tu-chemnitz.de/pub/linux/sunsite.unc-mirror/distributions/archlinux/extra/os/i686
Server = ftp://ftp.archlinux.org/extra/os/i686
@ -67,6 +70,7 @@ Server = ftp://ftp.rez-gif.supelec.fr/pub/Linux/distrib/archlinux/extra/os/i686
#Server = ftp://ftp.archlinux.org/release/os/i686
#Server = ftp://ftp.archlinux.de/pub/archlinux/release/os/i686
#Server = ftp://ftp.ibiblio.org/pub/linux/distributions/archlinux/release/os/i686
#Server = http://archlinux.antesis.org/release/os/i686
#Server = ftp://ftp.mpi-sb.mpg.de/pub/linux/mirror/ftp.ibiblio.org/pub/Linux/distributions/archlinux/release/os/i686
#Server = ftp://ftp.oit.unc.edu/pub/Linux/distributions/archlinux/release/os/i686
#Server = ftp://ftp.tu-chemnitz.de/pub/linux/sunsite.unc-mirror/distributions/archlinux/release/os/i686
@ -83,6 +87,7 @@ Server = ftp://ftp.rez-gif.supelec.fr/pub/Linux/distrib/archlinux/extra/os/i686
#Server = ftp://ftp.archlinux.org/unstable/os/i686
#Server = ftp://ftp.archlinux.de/pub/archlinux/unstable/os/i686
#Server = ftp://ftp.ibiblio.org/pub/linux/distributions/archlinux/unstable/os/i686
#Server = http://archlinux.antesis.org/unstable/os/i686
#Server = ftp://ftp.mpi-sb.mpg.de/pub/linux/mirror/ftp.ibiblio.org/pub/Linux/distributions/archlinux/unstable/os/i686
#Server = ftp://ftp.oit.unc.edu/pub/Linux/distributions/archlinux/unstable/os/i686
#Server = ftp://ftp.tu-chemnitz.de/pub/linux/sunsite.unc-mirror/distributions/archlinux/unstable/os/i686

View file

@ -20,7 +20,7 @@
# USA.
#
myver='2.8'
myver='2.8.1'
usage() {
echo "gensync $myver"

View file

@ -20,7 +20,7 @@
# USA.
#
myver='2.8'
myver='2.8.1'
startdir=`pwd`
PKGDEST=$startdir
USE_COLOR="n"

View file

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

114
src/db.c
View file

@ -25,6 +25,8 @@
#include <errno.h>
#include <string.h>
#include <sys/stat.h>
#include <libgen.h>
#include <unistd.h>
#include "package.h"
#include "util.h"
#include "db.h"
@ -540,6 +542,7 @@ PMList* db_find_conflicts(pacdb_t *db, PMList *targets, char *root)
char *str = NULL;
struct stat buf;
PMList *conflicts = NULL;
char *sym = NULL, *symw = NULL, *symlink = NULL, *tempsym = NULL;
/* CHECK 1: check every db package against every target package */
/* XXX: I've disabled the database-against-targets check for now, as the
@ -615,6 +618,114 @@ PMList* db_find_conflicts(pacdb_t *db, PMList *targets, char *root)
if(dbpkg && is_in(j->data, dbpkg->files)) {
ok = 1;
}
/* Make sure that the supposedly-conflicting file is not actually just
* a symlink that points to a path that used to exist in the package.
*/
/* XXX: Chu */
/* Check if any part of the conflicting file's path is a symlink */
if(dbpkg && !ok) {
if(!sym) MALLOC(sym, PATH_MAX);
if(!symlink) MALLOC(symlink, PATH_MAX);
if(!tempsym) MALLOC(tempsym, PATH_MAX);
strncpy(sym, path, PATH_MAX);
symw = sym;
do {
/* Is it a symlink? */
if(!lstat(sym, &buf) && S_ISLNK(buf.st_mode)) {
memset(symlink, 0, PATH_MAX);
readlink(sym, symlink, PATH_MAX);
if(symlink[0] != '/') {
char *temp = NULL;
MALLOC(temp, PATH_MAX);
strncpy(tempsym, symlink, PATH_MAX);
strncpy(temp, sym, PATH_MAX);
snprintf(symlink, PATH_MAX, "%s/%s", dirname(temp), tempsym);
FREE(temp);
}
if(strstr(symlink, root) == symlink) {
strncpy(tempsym, symlink+strlen(root), PATH_MAX-strlen(root));
/* If that part of the path used to exist in the package */
if(is_in(tempsym, dbpkg->files)) {
/* See if the modified path used to */
snprintf(tempsym, PATH_MAX, "%s%s", symlink+strlen(root), path+strlen(sym)+strlen(root));
printf("check1: is_in(%s, %s->files)\n", tempsym, p->name);
if(is_in(tempsym, dbpkg->files)) {
ok = 1;
break;
}
}
strncpy(tempsym, symlink, PATH_MAX);
snprintf(symlink, PATH_MAX, "%s/", tempsym);
strncpy(tempsym, symlink+strlen(root), PATH_MAX-strlen(root));
/* If that part of the path (explicitly check for directory) used to exist in the package */
if(is_in(tempsym, dbpkg->files)) {
/* See if the modified path used to */
snprintf(tempsym, PATH_MAX, "%s%s", symlink+strlen(root), path+strlen(sym)+strlen(root));
printf("check2: is_in(%s, %s->files)\n", tempsym, p->name);
if(is_in(tempsym, dbpkg->files)) {
ok = 1;
break;
}
}
}
}
symw = dirname(sym);
strncpy(sym, symw, PATH_MAX);
} while (strncmp(sym, root, PATH_MAX));
}
if(dbpkg && !ok) {
if(!sym) MALLOC(sym, PATH_MAX);
if(!symlink) MALLOC(symlink, PATH_MAX);
if(!tempsym) MALLOC(tempsym, PATH_MAX);
for(k = dbpkg->files; k; k = k->next) {
snprintf(sym, PATH_MAX, "%s%s", root, (char *)k->data);
/* If the last part of the path is '/' then toss it */
if(rindex(sym, '/') == sym+strlen(sym)-1) {
sym[strlen(sym)-1] = '\0';
}
/* Is that a symlink? */
if(!lstat(sym, &buf) && S_ISLNK(buf.st_mode)) {
memset(symlink, 0, PATH_MAX);
readlink(sym, symlink, PATH_MAX);
/* It's not an absolute symlink, make it one */
if(symlink[0] != '/') {
strncpy(tempsym, symlink, PATH_MAX);
snprintf(symlink, PATH_MAX, "%s/%s", dirname(sym), tempsym);
}
/* Does the symlink point to a part of the conflicting path? */
if(strstr(path, symlink) == path)
{
/* Replace one with the other and check if it really did exist in the old package */
snprintf(tempsym, PATH_MAX, "%s%s", symlink, path+strlen(symlink));
printf("check3: !strncmp(%s, %s)\n", tempsym, path);
if(!strncmp(tempsym, path, PATH_MAX)) {
ok = 1;
break;
}
}
}
}
}
/* Check if the conflicting file has been moved to another package/target */
if(!ok) {
/* Look at all the targets */
for(k = targets; k && !ok; k = k->next) {
pkginfo_t *p1 = (pkginfo_t*)k->data;
/* As long as they're not the current package */
if(strcmp(p1->name, p->name)) {
pkginfo_t *dbpkg2 = NULL;
dbpkg2 = db_scan(db, p1->name, INFRQ_DESC | INFRQ_FILES);
/* If it used to exist in there, but doesn't anymore */
if(!is_in(filestr, p1->files) && is_in(filestr, dbpkg2->files)) {
ok = 1;
}
FREE(dbpkg2);
}
}
}
/* XXX: Chu */
if(!ok) {
MALLOC(str, 512);
snprintf(str, 512, "%s: exists in filesystem", path);
@ -625,6 +736,9 @@ PMList* db_find_conflicts(pacdb_t *db, PMList *targets, char *root)
FREEPKG(dbpkg);
}
if(sym) FREE(sym);
if(symlink) FREE(symlink);
if(tempsym) FREE(tempsym);
return(conflicts);
}

View file

@ -62,6 +62,7 @@ unsigned short pmo_nodeps = 0;
unsigned short pmo_upgrade = 0;
unsigned short pmo_freshen = 0;
unsigned short pmo_nosave = 0;
unsigned short pmo_noconfirm = 0;
unsigned short pmo_d_vertest = 0;
unsigned short pmo_d_resolve = 0;
unsigned short pmo_q_isfile = 0;
@ -88,6 +89,7 @@ unsigned short pmo_proxyport = 0;
char *pmo_xfercommand = NULL;
PMList *pmo_noupgrade = NULL;
PMList *pmo_ignorepkg = NULL;
PMList *pmo_holdpkg = NULL;
unsigned short pmo_usesyslog = 0;
unsigned short pmo_nopassiveftp = 0;
@ -884,6 +886,7 @@ int pacman_sync(pacdb_t *db, PMList *targets)
}
if(!errorout) {
int found;
PMList *exfinal = NULL;
errorout = 0;
/* no unresolvable deps, so look for conflicts */
for(i = deps; i && !errorout; i = i->next) {
@ -891,6 +894,10 @@ int pacman_sync(pacdb_t *db, PMList *targets)
if(miss->type != CONFLICT) {
continue;
}
/* make sure this package wasn't already removed from the final list */
if(is_in(miss->target, exfinal)) {
continue;
}
/* check if the conflicting package is one that's about to be removed/replaced.
* if so, then just ignore it
@ -920,9 +927,41 @@ int pacman_sync(pacdb_t *db, PMList *targets)
* over to the replacing package
*/
pkginfo_t *q = db_scan(db, miss->depend.name, INFRQ_DESC | INFRQ_DEPENDS);
/* append to the replaces list */
sync->replaces = list_add(sync->replaces, q);
solved = 1;
if(q) {
/* append to the replaces list */
sync->replaces = list_add(sync->replaces, q);
solved = 1;
} else {
char *rmpkg = NULL;
/* hmmm, depend.name isn't installed, so it must be conflicting
* with another package in our final list. For example:
*
* pacman -S blackbox xfree86
*
* If no x-servers are installed and blackbox pulls in xorg, then
* xorg and xfree86 will conflict with each other. In this case,
* we should follow the user's preference and rip xorg out of final,
* opting for xfree86 instead.
*/
/* figure out which one was requested in targets. If they both were,
* then it's still an unresolvable conflict. */
if(is_in(miss->depend.name, targets) && !is_in(miss->target, targets)) {
/* remove miss->target */
rmpkg = strdup(miss->target);
} else if(is_in(miss->target, targets) && !is_in(miss->depend.name, targets)) {
/* remove miss->depend.name */
rmpkg = strdup(miss->depend.name);
} else {
/* something's not right, bail out with a conflict error */
}
if(rmpkg) {
final = rm_pkginsync(rmpkg, final);
/* add to the exfinal list */
exfinal = list_add(exfinal, rmpkg);
solved = 1;
}
}
}
}
if(!solved) {
@ -930,8 +969,8 @@ int pacman_sync(pacdb_t *db, PMList *targets)
*/
pkginfo_t p1;
/* build a "fake" pkginfo_t so we can search with is_pkgin() */
snprintf(p1.name, sizeof(p1.name), miss->depend.name);
sprintf(p1.version, "1.0-1");
strncpy(p1.name, miss->depend.name, sizeof(p1.name));
strcpy(p1.version, "1.0-1");
if(is_pkgin(&p1, pm_packages)) {
if(yesno(":: %s conflicts with %s. Remove %s? [Y/n] ",
@ -953,6 +992,7 @@ int pacman_sync(pacdb_t *db, PMList *targets)
}
}
}
FREELIST(exfinal);
}
list_free(deps);
if(errorout) {
@ -1040,13 +1080,21 @@ int pacman_sync(pacdb_t *db, PMList *targets)
confirm = 0;
if(allgood && final && final->data) {
if(pmo_s_downloadonly) {
confirm = yesno("\nProceed with download? [Y/n] ");
if(pmo_noconfirm) {
printf("\nBeginning upgrade process...\n");
} else {
confirm = yesno("\nProceed with download? [Y/n] ");
}
} else {
/* don't get any confirmation if we're called from makepkg */
if(pmo_d_resolve || pmo_s_printuris) {
confirm = 1;
} else {
confirm = yesno("\nProceed with upgrade? [Y/n] ");
if(pmo_noconfirm) {
printf("\nBeginning download...\n");
} else {
confirm = yesno("\nProceed with upgrade? [Y/n] ");
}
}
}
}
@ -1587,6 +1635,7 @@ int pacman_add(pacdb_t *db, PMList *targets)
}
printf("\n");
FREELIST(lp);
printf("\nerrors occurred, no packages were upgraded.\n");
return(1);
}
printf("done.\n");
@ -2045,6 +2094,18 @@ int pacman_remove(pacdb_t *db, PMList *targets)
fprintf(stderr, "error: could not find %s in database\n", (char*)lp->data);
return(1);
}
if(pmo_op == PM_REMOVE) {
/* check if the package is in the HoldPkg list. If so, ask
* confirmation first */
for(j = pmo_holdpkg; j && j->data; j = j->next) {
if(!strcmp(info->name, j->data)) {
if(!yesno(":: %s is designated as a HoldPkg. Remove anyway? [Y/n] ", info->name)) {
return(1);
}
break;
}
}
}
alltargs = list_add(alltargs, info);
}
if(!pmo_nodeps && !pmo_upgrade) {
@ -3194,6 +3255,7 @@ int parseargs(int op, int argc, char **argv)
{"cascade", no_argument, 0, 'c'},
{"recursive", no_argument, 0, 's'},
{"groups", no_argument, 0, 'g'},
{"noconfirm", no_argument, 0, 999},
{0, 0, 0, 0}
};
@ -3203,6 +3265,7 @@ int parseargs(int op, int argc, char **argv)
}
switch(opt) {
case 0: break;
case 999: pmo_noconfirm = 1; break;
case 'A': pmo_op = (pmo_op != PM_MAIN ? 0 : PM_ADD); break;
case 'R': pmo_op = (pmo_op != PM_MAIN ? 0 : PM_REMOVE); break;
case 'U': pmo_op = (pmo_op != PM_MAIN ? 0 : PM_UPGRADE); break;
@ -3360,6 +3423,18 @@ int parseconfig(char *configfile)
}
pmo_ignorepkg = list_add(pmo_ignorepkg, strdup(p));
vprint("config: ignorepkg: %s\n", p);
} else if(!strcmp(key, "HOLDPKG")) {
char *p = ptr;
char *q;
while((q = strchr(p, ' '))) {
*q = '\0';
pmo_holdpkg = list_add(pmo_holdpkg, strdup(p));
vprint("config: holdpkg: %s\n", p);
p = q;
p++;
}
pmo_holdpkg = list_add(pmo_holdpkg, strdup(p));
vprint("config: holdpkg: %s\n", p);
} else if(!strcmp(key, "DBPATH")) {
/* shave off the leading slash, if there is one */
if(*ptr == '/') {
@ -3530,9 +3605,10 @@ void usage(int op, char *myname)
printf(" -p, --print-uris print out download URIs for each package to be installed\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(" -w, --downloadonly download packages but do not install/upgrade anything\n");
printf(" -y, --refresh download fresh package databases from the server\n");
}
printf(" --noconfirm do not ask for any confirmation\n");
printf(" -v, --verbose be verbose\n");
printf(" -r, --root <path> set an alternate installation root\n");
printf(" -b, --dbpath <path> set an alternate database location\n");
@ -3618,6 +3694,29 @@ char* buildstring(PMList *strlist)
return(str);
}
/* presents a prompt and gets a Y/N answer */
int yesno(char *fmt, ...)
{
char response[32];
va_list args;
if(pmo_noconfirm) {
/* --noconfirm was set, we don't have to ask permission! */
return(1);
}
va_start(args, fmt);
vprintf(fmt, args);
va_end(args);
fflush(stdout);
if(fgets(response, 32, stdin)) {
trim(response);
if(!strcasecmp(response, "Y") || !strcasecmp(response, "YES") || !strlen(response)) {
return(1);
}
}
return(0);
}
int lckmk(char *file, int retries, unsigned int sleep_secs)
{
@ -3690,5 +3789,6 @@ void cleanup(int signum)
exit(signum);
}
/* vim: set ts=2 sw=2 noet: */

View file

@ -22,7 +22,7 @@
#define _PAC_PACMAN_H
#ifndef PACVER
#define PACVER "2.8"
#define PACVER "2.8.1"
#endif
#ifndef PKGDIR
@ -71,6 +71,7 @@ void version(void);
void vprint(char *fmt, ...);
void logaction(FILE *fp, char *fmt, ...);
char* buildstring(PMList *strlist);
int yesno(char* fmt, ...);
int lckmk(char *file, int retries, unsigned int sleep_secs);
int lckrm(char *lckfile);
void cleanup(int signum);

View file

@ -40,9 +40,9 @@ static int log_progress(netbuf *ctl, int xfered, void *arg);
static char sync_fnm[25];
static int offset;
static struct timeval t0, t;
static float rate;
static int xfered1;
static unsigned char eta_h, eta_m, eta_s;
static float rate;
static int xfered1;
static unsigned char eta_h, eta_m, eta_s;
/* pacman options */
extern char *pmo_root;
@ -457,4 +457,29 @@ syncpkg_t* find_pkginsync(char *needle, PMList *haystack)
return sync;
}
/* Remove a package from a list of syncpkg_t elements
*/
PMList* rm_pkginsync(char *needle, PMList *haystack)
{
PMList *i;
syncpkg_t *sync = NULL;
PMList *newlist = NULL;
for(i = haystack; i; i = i->next) {
sync = (syncpkg_t*)i->data;
if(!sync) continue;
if(strcmp(sync->pkg->name, needle)) {
newlist = list_add(newlist, sync);
} else {
FREEPKG(sync->pkg);
FREELISTPKGS(sync->replaces);
FREE(sync);
}
i->data = NULL;
}
FREELIST(haystack);
return newlist;
}
/* vim: set ts=2 sw=2 noet: */

View file

@ -50,6 +50,7 @@ typedef struct __syncpkg_t {
int sync_synctree();
int downloadfiles(PMList *servers, const char *localpath, PMList *files);
syncpkg_t* find_pkginsync(char *needle, PMList *haystack);
PMList* rm_pkginsync(char *needle, PMList *haystack);
#endif

View file

@ -202,25 +202,6 @@ int rmrf(char *path)
return(0);
}
/* presents a prompt and gets a Y/N answer */
int yesno(char *fmt, ...)
{
char response[32];
va_list args;
va_start(args, fmt);
vprintf(fmt, args);
va_end(args);
fflush(stdout);
if(fgets(response, 32, stdin)) {
trim(response);
if(!strcasecmp(response, "Y") || !strcasecmp(response, "YES") || !strlen(response)) {
return(1);
}
}
return(0);
}
/* output a string, but wrap words properly with a specified indentation
*/
void indentprint(char *str, int indent)

View file

@ -34,7 +34,6 @@ int copyfile(char *src, char *dest);
int makepath(char *path);
int rmrf(char *path);
void indentprint(char *str, int indent);
int yesno(char* fmt, ...);
char* trim(char *str);
char* strtoupper(char *str);
int grep(const char *fn, const char *needle);