1 /* $NetBSD: check.c,v 1.1 2008/03/09 19:02:27 joerg Exp $ */
11 __RCSID("$NetBSD: check.c,v 1.1 2008/03/09 19:02:27 joerg Exp $");
15 * Copyright (c) 1999-2008 The NetBSD Foundation, Inc.
16 * All rights reserved.
18 * This code is derived from software contributed to The NetBSD Foundation
19 * by Hubert Feyrer <hubert@feyrer.de>.
21 * Redistribution and use in source and binary forms, with or without
22 * modification, are permitted provided that the following conditions
24 * 1. Redistributions of source code must retain the above copyright
25 * notice, this list of conditions and the following disclaimer.
26 * 2. Redistributions in binary form must reproduce the above copyright
27 * notice, this list of conditions and the following disclaimer in the
28 * documentation and/or other materials provided with the distribution.
29 * 3. All advertising materials mentioning features or use of this software
30 * must display the following acknowledgement:
31 * This product includes software developed by the NetBSD
32 * Foundation, Inc. and its contributors.
33 * 4. Neither the name of The NetBSD Foundation nor the names of its
34 * contributors may be used to endorse or promote products derived
35 * from this software without specific prior written permission.
37 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
38 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
39 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
40 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
41 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
42 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
43 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
44 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
45 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
46 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
47 * POSSIBILITY OF SUCH DAMAGE.
51 #include <sys/types.h>
84 static int checkpattern_fn(const char *, void *);
87 * Assumes CWD is in /var/db/pkg/<pkg>!
90 check1pkg(const char *pkgdir, int *filecnt, int *pkgcnt)
95 char *PkgName, *dirp = NULL, *md5file;
96 char file[MaxPathSize];
97 char dir[MaxPathSize];
100 content = pkgdb_pkg_file(pkgdir, CONTENTS_FNAME);
101 f = fopen(content, "r");
103 err(EXIT_FAILURE, "can't open %s", content);
106 Plist.head = Plist.tail = NULL;
107 read_plist(&Plist, f);
108 p = find_plist(&Plist, PLIST_NAME);
110 errx(EXIT_FAILURE, "Package %s has no @name, aborting.",
113 for (p = Plist.head; p; p = p->next) {
117 warnx("dirp not initialized, please send-pr!");
121 (void) snprintf(file, sizeof(file), "%s/%s", dirp, p->name);
123 if (isfile(file) || islinktodir(file)) {
124 if (p->next && p->next->type == PLIST_COMMENT) {
125 if (strncmp(p->next->name, CHECKSUM_HEADER, ChecksumHeaderLen) == 0) {
126 if ((md5file = MD5File(file, NULL)) != NULL) {
129 printf("%s: md5 should=<%s>, is=<%s>\n",
130 file, p->next->name + ChecksumHeaderLen, md5file);
132 if (strcmp(md5file, p->next->name + ChecksumHeaderLen) != 0)
133 printf("%s fails MD5 checksum\n", file);
137 } else if (strncmp(p->next->name, SYMLINK_HEADER, SymlinkHeaderLen) == 0) {
138 char buf[MaxPathSize + SymlinkHeaderLen];
141 (void) strlcpy(buf, SYMLINK_HEADER, sizeof(buf));
142 if ((cc = readlink(file, &buf[SymlinkHeaderLen],
143 sizeof(buf) - SymlinkHeaderLen - 1)) < 0) {
144 warnx("can't readlink `%s'", file);
146 buf[SymlinkHeaderLen + cc] = 0x0;
147 if (strcmp(buf, p->next->name) != 0) {
148 printf("symlink (%s) is not same as recorded value, %s: %s\n",
149 file, buf, p->next->name);
156 } else if (isbrokenlink(file)) {
157 warnx("%s: Symlink `%s' exists and is in %s but target does not exist!", PkgName, file, CONTENTS_FNAME);
159 warnx("%s: File `%s' is in %s but not on filesystem!", PkgName, file, CONTENTS_FNAME);
163 if (strcmp(p->name, ".") != 0)
166 (void) snprintf(dir, sizeof(dir), "%s/%s", _pkgdb_getPKGDB_DIR(), pkgdir);
186 case PLIST_IGNORE_INST:
198 struct checkpattern_arg {
205 checkpattern_fn(const char *pkg, void *vp)
207 struct checkpattern_arg *arg = vp;
209 check1pkg(pkg, &arg->filecnt, &arg->pkgcnt);
219 check_pkg(const char *pkg, int *filecnt, int *pkgcnt, int allow_unmatched)
221 struct checkpattern_arg arg;
224 arg.filecnt = *filecnt;
225 arg.pkgcnt = *pkgcnt;
228 if (match_installed_pkgs(pkg, checkpattern_fn, &arg) == -1)
229 errx(EXIT_FAILURE, "Cannot process pkdbdb");
230 if (arg.got_match != 0) {
231 *filecnt = arg.filecnt;
232 *pkgcnt = arg.pkgcnt;
236 if (ispkgpattern(pkg)) {
239 errx(EXIT_FAILURE, "No matching pkg for %s.", pkg);
242 if (asprintf(&pattern, "%s-[0-9]*", pkg) == -1)
243 errx(EXIT_FAILURE, "asprintf failed");
245 if (match_installed_pkgs(pattern, checkpattern_fn, &arg) == -1)
246 errx(EXIT_FAILURE, "Cannot process pkdbdb");
248 if (arg.got_match == 0)
249 errx(EXIT_FAILURE, "cannot find package %s", pkg);
252 *filecnt = arg.filecnt;
253 *pkgcnt = arg.pkgcnt;
263 setbuf(stdout, NULL);
266 check_pkg("*", &filecnt, &pkgcnt, 1);
268 for (; *argv != NULL; ++argv)
269 check_pkg(*argv, &filecnt, &pkgcnt, 0);
273 printf("Checked %d file%s from %d package%s.\n",
274 filecnt, (filecnt == 1) ? "" : "s",
275 pkgcnt, (pkgcnt == 1) ? "" : "s");