* Add explicit conflict-checking to the package tools. Packages can
register a list of other packages with which they conflict (via the -C option to pkg_create), and they will refuse to install (unless -f is specified) if one of the listed packages is already present. * Update documentation for the new feature as well as fleshing out some existing documentation. * Bump PKG_INSTALL_VERSION so this feature can be tested for. Submitted by: Sergey Matveychuk <sem@ciam.ru> PR: bin/47145 MFC after: 2 weeks
This commit is contained in:
parent
c72e7314c2
commit
7f6bf1d8ce
@ -71,13 +71,16 @@ pkg_do(char *pkg)
|
||||
int code;
|
||||
PackingList p;
|
||||
struct stat sb;
|
||||
int inPlace;
|
||||
int inPlace, conflictsfound, i, errcode;
|
||||
/* support for separate pre/post install scripts */
|
||||
int new_m = 0;
|
||||
char pre_script[FILENAME_MAX] = INSTALL_FNAME;
|
||||
char post_script[FILENAME_MAX];
|
||||
char pre_arg[FILENAME_MAX], post_arg[FILENAME_MAX];
|
||||
char *conflict[2];
|
||||
char **matched;
|
||||
|
||||
conflictsfound = 0;
|
||||
code = 0;
|
||||
zapLogDir = 0;
|
||||
LogDir[0] = '\0';
|
||||
@ -248,6 +251,33 @@ pkg_do(char *pkg)
|
||||
goto success; /* close enough for government work */
|
||||
}
|
||||
|
||||
/* Now check the packing list for conflicts */
|
||||
for (p = Plist.head; p != NULL; p = p->next) {
|
||||
if (p->type == PLIST_CONFLICTS) {
|
||||
conflict[0] = strdup(p->name);
|
||||
conflict[1] = NULL;
|
||||
matched = matchinstalled(MATCH_GLOB, conflict, &errcode);
|
||||
free(conflict[0]);
|
||||
if (errcode == 0 && matched != NULL)
|
||||
for (i = 0; matched[i] != NULL; i++)
|
||||
if (isinstalledpkg(matched[i])) {
|
||||
warnx("package '%s' conflicts with %s", Plist.name,
|
||||
matched[i]);
|
||||
conflictsfound = 1;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if(conflictsfound) {
|
||||
if(!Force) {
|
||||
warnx("please use pkg_delete first to remove conflicting package(s) or -f to force installation");
|
||||
code = 1;
|
||||
goto bomb;
|
||||
} else
|
||||
warnx("-f specified; proceeding anyway");
|
||||
}
|
||||
|
||||
/* Now check the packing list for dependencies */
|
||||
for (p = Plist.head; p ; p = p->next) {
|
||||
char *deporigin;
|
||||
|
@ -208,20 +208,29 @@ ftp.
|
||||
.Sh TECHNICAL DETAILS
|
||||
The
|
||||
.Nm
|
||||
utility is fairly simple. It extracts each package's "packing list"
|
||||
into a special staging directory, parses it,
|
||||
and then runs through the following sequence to fully extract the contents:
|
||||
utility extracts each package's "packing list" into a special staging
|
||||
directory in /tmp (or $PKG_TMPDIR if set), parses it, and then runs
|
||||
through the following sequence to fully extract the contents of the package:
|
||||
.Bl -enum
|
||||
.It
|
||||
Check if the package is already recorded as installed. If so,
|
||||
terminate installation.
|
||||
A check is made to determine if the package is already recorded as installed.
|
||||
If it is, installation is terminated.
|
||||
.It
|
||||
A check is made to determine if the package conflicts (from
|
||||
.Cm @conflicts
|
||||
directives, see
|
||||
.Xr pkg_create 1 )
|
||||
with an already-installed package.
|
||||
If it is, installation is terminated.
|
||||
.It
|
||||
Scan all the package dependencies (from
|
||||
.Cm @pkgdep
|
||||
directives, see
|
||||
.Xr pkg_create 1 )
|
||||
and make sure each one is met. If not, try and find the missing
|
||||
dependencies' packages and auto-install them; if they can't be found
|
||||
are read from the packing list.
|
||||
If any of these required packages is not currently installed,
|
||||
an attempt is made to find and install it;
|
||||
if the missing package cannot be found or installed,
|
||||
the installation is terminated.
|
||||
.It
|
||||
Search for any
|
||||
@ -388,7 +397,9 @@ period.
|
||||
.Pp
|
||||
The environment variable
|
||||
.Ev PKG_DBDIR
|
||||
specifies an alternative location for the installed package database.
|
||||
specifies an alternative location for the installed package database,
|
||||
default location is
|
||||
.Pa /var/db/pkg .
|
||||
.Pp
|
||||
The environment variables
|
||||
.Ev PKG_TMPDIR
|
||||
|
@ -37,6 +37,7 @@ extern char *SrcDir;
|
||||
extern char *ExcludeFrom;
|
||||
extern char *Mtree;
|
||||
extern char *Pkgdeps;
|
||||
extern char *Conflicts;
|
||||
extern char *Origin;
|
||||
extern char *InstalledPkg;
|
||||
extern char PlayPen[];
|
||||
|
@ -16,7 +16,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include "lib.h"
|
||||
#include "create.h"
|
||||
|
||||
static char Options[] = "YNOhjvyzf:p:P:c:d:i:I:k:K:r:t:X:D:m:s:o:b:";
|
||||
static char Options[] = "YNOhjvyzf:p:P:C:c:d:i:I:k:K:r:t:X:D:m:s:o:b:";
|
||||
|
||||
char *Prefix = NULL;
|
||||
char *Comment = NULL;
|
||||
@ -32,6 +32,7 @@ char *Require = NULL;
|
||||
char *ExcludeFrom = NULL;
|
||||
char *Mtree = NULL;
|
||||
char *Pkgdeps = NULL;
|
||||
char *Conflicts = NULL;
|
||||
char *Origin = NULL;
|
||||
char *InstalledPkg = NULL;
|
||||
char PlayPen[FILENAME_MAX];
|
||||
@ -78,6 +79,10 @@ main(int argc, char **argv)
|
||||
Contents = optarg;
|
||||
break;
|
||||
|
||||
case 'C':
|
||||
Conflicts = optarg;
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
Comment = optarg;
|
||||
break;
|
||||
@ -195,11 +200,11 @@ static void
|
||||
usage()
|
||||
{
|
||||
fprintf(stderr, "%s\n%s\n%s\n%s\n%s\n%s\n",
|
||||
"usage: pkg_create [-YNOhvy] [-P pkgs] [-p prefix] [-f contents] [-i iscript]",
|
||||
" [-I piscript] [-k dscript] [-K pdscript] [-r rscript] ",
|
||||
" [-t template] [-X excludefile] [-D displayfile] ",
|
||||
" [-m mtreefile] [-o origin] -c comment -d description ",
|
||||
" -f packlist pkg-filename",
|
||||
"usage: pkg_create [-YNOhvy] [-P pkgs] [-C conflicts] [-p prefix] [-f contents] ",
|
||||
" [-i iscript] [-I piscript] [-k dscript] [-K pdscript] ",
|
||||
" [-r rscript] [-t template] [-X excludefile] ",
|
||||
" [-D displayfile] [-m mtreefile] [-o origin] ",
|
||||
" -c comment -d description -f packlist pkg-filename",
|
||||
" pkg_create [-YNhvy] -b pkg-name [pkg-filename]");
|
||||
exit(1);
|
||||
}
|
||||
|
@ -145,6 +145,22 @@ pkg_perform(char **pkgs)
|
||||
printf(".\n");
|
||||
}
|
||||
|
||||
/* Put the conflicts directly after the dependencies, if any */
|
||||
if (Conflicts) {
|
||||
if (Verbose && !PlistOnly)
|
||||
printf("Registering conflicts:");
|
||||
while (Conflicts) {
|
||||
cp = strsep(&Conflicts, " \t\n");
|
||||
if (*cp) {
|
||||
add_plist(&plist, PLIST_CONFLICTS, cp);
|
||||
if (Verbose && !PlistOnly)
|
||||
printf(" %s", cp);
|
||||
}
|
||||
}
|
||||
if (Verbose && !PlistOnly)
|
||||
printf(".\n");
|
||||
}
|
||||
|
||||
/* If a SrcDir override is set, add it now */
|
||||
if (SrcDir) {
|
||||
if (Verbose && !PlistOnly)
|
||||
|
@ -32,6 +32,7 @@
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Op Fl YNOhjvyz
|
||||
.Op Fl C Ar conflicts
|
||||
.Op Fl P Ar pkgs
|
||||
.Op Fl p Ar prefix
|
||||
.Op Fl f Ar contents
|
||||
@ -142,6 +143,13 @@ executable program (or shell script). It will be invoked automatically
|
||||
when the package is later installed.
|
||||
It will be passed the package's name as
|
||||
the first argument.
|
||||
.It Fl C Ar conflicts
|
||||
Set the initial package conflict list to
|
||||
.Ar conflicts .
|
||||
This is assumed to be a whitespace separated list of package names
|
||||
and is meant as a convenient shorthand for specifying multiple
|
||||
.Cm @conflicts
|
||||
directives in the packing list (see PACKING LIST DETAILS section below).
|
||||
.It Fl P Ar pkgs
|
||||
Set the initial package dependency list to
|
||||
.Ar pkgs .
|
||||
@ -482,6 +490,11 @@ installed, and this package must be deinstalled before the
|
||||
package is deinstalled. Multiple
|
||||
.Cm @pkgdep
|
||||
directives may be used if the package depends on multiple other packages.
|
||||
.It Cm @conflicts Ar pkgcflname
|
||||
Declare a conflict with the
|
||||
.Ar pkgcflname
|
||||
package, as the two packages contain references to the same files,
|
||||
and so cannot co-exist on the same system.
|
||||
.El
|
||||
.Sh ENVIRONMENT
|
||||
The environment variable
|
||||
|
@ -158,6 +158,10 @@ show_plist(const char *title, Package *plist, plist_t type, Boolean showall)
|
||||
"\tdependency origin: %s\n", p->name);
|
||||
break;
|
||||
|
||||
case PLIST_CONFLICTS:
|
||||
printf(Quiet ? "@conflicts %s\n" : "Conflicts: %s\n", p->name);
|
||||
break;
|
||||
|
||||
case PLIST_MTREE:
|
||||
printf(Quiet ? "@mtree %s\n" : "\tPackage mtree file: %s\n", p->name);
|
||||
break;
|
||||
|
@ -86,7 +86,7 @@
|
||||
* Version of the package tools - increase only when some
|
||||
* functionality used by bsd.port.mk is changed, added or removed
|
||||
*/
|
||||
#define PKG_INSTALL_VERSION 20020908
|
||||
#define PKG_INSTALL_VERSION 20030417
|
||||
|
||||
#define PKG_WRAPCONF_FNAME "/var/db/pkg_install.conf"
|
||||
#define main(argc, argv) real_main(argc, argv)
|
||||
@ -99,8 +99,8 @@ enum _plist_t {
|
||||
PLIST_FILE, PLIST_CWD, PLIST_CMD, PLIST_CHMOD,
|
||||
PLIST_CHOWN, PLIST_CHGRP, PLIST_COMMENT, PLIST_IGNORE,
|
||||
PLIST_NAME, PLIST_UNEXEC, PLIST_SRC, PLIST_DISPLAY,
|
||||
PLIST_PKGDEP, PLIST_MTREE, PLIST_DIR_RM, PLIST_IGNORE_INST,
|
||||
PLIST_OPTION, PLIST_ORIGIN, PLIST_DEPORIGIN
|
||||
PLIST_PKGDEP, PLIST_CONFLICTS, PLIST_MTREE, PLIST_DIR_RM,
|
||||
PLIST_IGNORE_INST, PLIST_OPTION, PLIST_ORIGIN, PLIST_DEPORIGIN
|
||||
};
|
||||
typedef enum _plist_t plist_t;
|
||||
|
||||
|
@ -241,6 +241,8 @@ plist_cmd(const char *s, char **arg)
|
||||
return PLIST_DISPLAY;
|
||||
else if (!strcmp(cmd, "pkgdep"))
|
||||
return PLIST_PKGDEP;
|
||||
else if (!strcmp(cmd, "conflicts"))
|
||||
return PLIST_CONFLICTS;
|
||||
else if (!strcmp(cmd, "mtree"))
|
||||
return PLIST_MTREE;
|
||||
else if (!strcmp(cmd, "dirrm"))
|
||||
@ -364,6 +366,10 @@ write_plist(Package *pkg, FILE *fp)
|
||||
fprintf(fp, "%cpkgdep %s\n", CMD_CHAR, plist->name);
|
||||
break;
|
||||
|
||||
case PLIST_CONFLICTS:
|
||||
fprintf(fp, "%cconflicts %s\n", CMD_CHAR, plist->name);
|
||||
break;
|
||||
|
||||
case PLIST_MTREE:
|
||||
fprintf(fp, "%cmtree %s\n", CMD_CHAR, plist->name);
|
||||
break;
|
||||
|
Loading…
Reference in New Issue
Block a user