1 /* $NetBSD: conflicts.c,v 1.9 2009/08/02 17:56:45 joerg Exp $ */
4 * Copyright (c) 2007 Roland Illig <rillig@NetBSD.org>.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
21 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
22 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
23 * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
24 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
26 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
28 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * XXX: Reading the +CONTENTS files of all installed packages is
34 * rather slow. Since this check is necessary to avoid conflicting
35 * packages, it should not be removed.
37 * TODO: Put all the information that is currently in the +CONTENTS
38 * files into one large file or another database.
48 #include <sys/cdefs.h>
51 __RCSID("$NetBSD: conflicts.c,v 1.9 2009/08/02 17:56:45 joerg Exp $");
61 * Data structure to keep the intermediate result of the conflict
62 * search. ''pkgname'' is the package in question. The first
63 * installed package that conflicts is filled into
64 * ''conflicting_pkgname''. The pattern that leads to the conflict is
65 * also filled in to help the user in deciding what to do with the
68 struct package_conflict
{
70 const char *skip_pkgname
;
71 char **conflicting_pkgname
;
72 char **conflicting_pattern
;
76 fopen_contents(const char *pkgname
, const char *mode
)
78 char fname
[MaxPathSize
];
81 snprintf(fname
, sizeof(fname
), "%s/%s/%s", _pkgdb_getPKGDB_DIR(), pkgname
, CONTENTS_FNAME
);
82 f
= fopen(fname
, mode
);
84 err(EXIT_FAILURE
, "%s", fname
);
92 check_package_conflict(const char *pkgname
, void *v
)
94 struct package_conflict
*conflict
= v
;
100 if (conflict
->skip_pkgname
!= NULL
&&
101 strcmp(conflict
->skip_pkgname
, pkgname
) == 0)
106 f
= fopen_contents(pkgname
, "r");
110 for (p
= pkg
.head
; p
; p
= p
->next
) {
111 if (p
->type
!= PLIST_PKGCFL
)
114 if (pkg_match(p
->name
, conflict
->pkgname
) == 1) {
115 *(conflict
->conflicting_pkgname
) = xstrdup(pkgname
);
116 *(conflict
->conflicting_pattern
) = xstrdup(p
->name
);
117 rv
= 1 /* nonzero, stop iterating */;
127 * Checks if some installed package has a pkgcfl entry that matches
128 * PkgName. If such an entry is found, the package name is returned in
129 * inst_pkgname, the matching pattern in inst_pattern, and the function
130 * returns a non-zero value. Otherwise, zero is returned and the result
131 * variables are set to NULL.
134 some_installed_package_conflicts_with(const char *pkgname
,
135 const char *skip_pkgname
, char **inst_pkgname
, char **inst_pattern
)
137 struct package_conflict cfl
;
140 cfl
.pkgname
= pkgname
;
141 cfl
.skip_pkgname
= skip_pkgname
;
142 *inst_pkgname
= NULL
;
143 *inst_pattern
= NULL
;
144 cfl
.conflicting_pkgname
= inst_pkgname
;
145 cfl
.conflicting_pattern
= inst_pattern
;
146 rv
= iterate_pkg_db(check_package_conflict
, &cfl
);
148 errx(EXIT_FAILURE
, "Couldn't read list of installed packages.");
151 return *inst_pkgname
!= NULL
;
155 int main(int argc
, char **argv
)
159 if (some_installed_package_conflicts_with(argv
[1], &pkg
, &patt
))
160 printf("yes: package %s conflicts with %s, pattern %s\n", pkg
, argv
[1], patt
);