4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
28 /* All Rights Reserved */
38 #include <sys/types.h>
40 #include <sys/param.h>
50 extern int qflag
, lflag
, Lflag
, pkgcnt
;
53 extern char *basedir
, *pathlist
[], *ppathlist
[], **pkg
, **environ
;
56 extern struct cfent
**eptlist
;
59 extern int ckentry(int, int, struct cfent
*, VFP_T
*, PKGserver
);
61 #define NXTENTRY(P, VFP, SRV) \
62 (maptyp ? srchcfile((P), "*", (SRV)) : \
63 gpkgmapvfp((P), (VFP)))
65 #define MSG_ARCHIVE "NOTE: some pathnames are in private formats " \
66 "and cannot be verified"
67 #define WRN_NOPKG "WARNING: no pathnames were associated with <%s>"
68 #define WRN_NOPATH "WARNING: no information associated with pathname <%s>"
69 #define EMPTY_PKG "WARNING: Package <%s> is installed but empty"
70 #define ERR_NOMEM "unable to allocate dynamic memory, errno=%d"
71 #define ERR_PKGMAP "unable to open pkgmap file <%s>"
72 #define ERR_ENVFILE "unable to open environment file <%s>"
74 static struct cfent entry
;
76 static int shellmatch(char *, char *);
77 static int is_partial_path_in_DB(char *, char *);
79 int selpath(char *, int);
83 * This routine checks all files which are referenced in the pkgmap which is
84 * identified by the mapfile arg. When the package is installed, the mapfile
85 * may be the contents file or a separate pkgmap (maptyp tells the function
86 * which it is). The variable uninst tells the function whether the package
87 * is in the installed state or not. The envfile entry is usually a pkginfo
88 * file, but it could be any environment parameter list.
92 checkmap(int maptyp
, int uninst
, char *mapfile
, char *envfile
,
93 char *pkginst
, char *path
, int pathtype
)
98 char param
[MAX_PKG_PARAM_LENGTH
];
104 VFP_T
*vfp
= (VFP_T
*)NULL
;
107 if (envfile
!= NULL
) {
108 if ((fp
= fopen(envfile
, "r")) == NULL
) {
109 progerr(gettext(ERR_ENVFILE
), envfile
);
113 while (value
= fpkgparam(fp
, param
)) {
114 if (strcmp("PATH", param
) != 0) {
116 * If checking an uninstalled package, we
117 * only want two parameters. If we took all
118 * of them, including path definitions, we
119 * wouldn't be looking in the right places in
120 * the reloc and root directories.
123 if ((strncmp("PKG_SRC_NOVERIFY", param
,
124 16) == 0) && value
) {
125 logerr(gettext(MSG_ARCHIVE
));
126 putparam(param
, value
);
128 if ((strncmp("CLASSES", param
,
130 putparam(param
, value
);
132 putparam(param
, value
);
140 basedir
= getenv("BASEDIR");
144 * If we are using a contents file for the map, this locks the
145 * contents file in order to freeze the database and assure it
146 * remains synchronized with the file system against which it is
147 * being compared. There is no practical way to lock another pkgmap
148 * on some unknown medium so we don't bother.
150 if (maptyp
) { /* If this is the contents file */
151 if (!socfile(&server
, B_FALSE
) ||
152 pkgopenfilter(server
, pkgcnt
== 1 ? pkginst
: NULL
) != 0) {
153 progerr(gettext(ERR_PKGMAP
), "contents");
157 if (vfpOpen(&vfp
, mapfile
, "r", VFP_NONE
) != 0) {
158 progerr(gettext(ERR_PKGMAP
), mapfile
);
163 if ((cl
= getenv("CLASSES")) != NULL
)
164 cl_sets(qstrdup(cl
));
169 if ((n
= NXTENTRY(&entry
, vfp
, server
)) == 0) {
173 * Search for partial paths in the ext DB.
176 /* LINTED warning: statement has no consequent: if */
177 if (is_partial_path_in_DB(entry
.path
, path
)) {
178 /* Check this entry */
180 } else if (entry
.ftype
== 's' || entry
.ftype
== 'l') {
181 if (is_partial_path_in_DB(
182 /* LINTED warning: statement has no consequen */
183 entry
.ainfo
.local
, path
)) {
184 /* Check this entry */
190 /* Skip to next DB entry */
196 char *errstr
= getErrstr();
197 logerr(gettext("ERROR: garbled entry"));
198 logerr(gettext("pathname: %s"),
199 (entry
.path
&& *entry
.path
) ? entry
.path
:
201 logerr(gettext("problem: %s"),
202 (errstr
&& *errstr
) ? errstr
: "Unknown");
206 break; /* done with file */
209 * The class list may not be complete for good reason, so
210 * there's no complaining if this returns an index of -1.
213 entry
.pkg_class_idx
= cl_idx(entry
.pkg_class
);
215 if (maptyp
&& pkginst
!= NULL
) {
217 * check to see if the entry we just read
218 * is associated with one of the packages
219 * we have listed on the command line
224 if (selpkg(pinfo
->pkg
)) {
231 continue; /* not selected */
235 * Check to see if the pathname associated with the entry
236 * we just read is associated with the list of paths we
237 * supplied on the command line
239 if (!selpath(entry
.path
, pathtype
))
240 continue; /* not selected */
243 * Determine if this is a package object wanting
244 * verification. Metafiles are always checked, otherwise, we
245 * rely on the class to discriminate.
247 if (entry
.ftype
!= 'i')
248 /* If there's no class list... */
251 * ... or this entry isn't in that class list
252 * or it's in a private format, then don't
255 if (entry
.pkg_class_idx
== -1 ||
256 cl_svfy(entry
.pkg_class_idx
) == NOVERIFY
)
260 if (ckentry((envfile
? 1 : 0), maptyp
, &entry
, vfp
, server
))
267 (void) vfpClose(&vfp
);
270 /* free up environment resources */
271 for (n
= 0; environ
[n
]; n
++)
279 * make sure each listed package was associated with
280 * an entry from the prototype or pkgmap
284 if (!qflag
&& !lflag
&& !Lflag
) {
286 * make sure each listed pathname was associated with an entry
287 * from the prototype or pkgmap
289 (void) selpath(NULL
, pathtype
);
297 static char *selected
;
303 if (selected
== NULL
) {
305 for (i
= 0; i
< pkgcnt
; ++i
) {
307 root
= get_inst_root();
311 "%s/var/sadm/pkg/%s/pkginfo",
316 "/var/sadm/pkg/%s/pkginfo",
319 if (access(buf
, F_OK
))
320 logerr(gettext(WRN_NOPKG
),
323 logerr(gettext(EMPTY_PKG
),
328 for (i
= 0; i
< pkgcnt
; ++i
) {
329 if (selected
[i
] == NULL
) {
330 root
= get_inst_root();
334 "%s/var/sadm/pkg/%s/pkginfo",
339 "/var/sadm/pkg/%s/pkginfo",
342 if (access(buf
, F_OK
))
343 logerr(gettext(WRN_NOPKG
),
346 logerr(gettext(EMPTY_PKG
),
351 return (0); /* return value not important */
352 } else if (pkgcnt
== 0)
354 else if (selected
== NULL
) {
356 (char *)calloc((unsigned)(pkgcnt
+1), sizeof (char));
357 if (selected
== NULL
) {
358 progerr(gettext(ERR_NOMEM
), errno
);
364 for (i
= 0; i
< pkgcnt
; ++i
) {
365 if (pkgnmchk(p
, pkg
[i
], 0) == 0) {
366 if (selected
!= NULL
)
375 selpath(char *path
, int partial_path
)
380 return (1); /* everything is selectable */
382 for (n
= 0; n
< npaths
; n
++) {
385 logerr(gettext(WRN_NOPATH
),
386 partial_path
? ppathlist
[n
] :
388 } else if (partial_path
) {
391 } else if (!shellmatch(pathlist
[n
], path
)) {
396 return (0); /* not selected */
400 shellmatch(char *spec
, char *path
)
402 /* Check if the value is NULL */
403 if (spec
== NULL
|| path
== NULL
)
406 while (*spec
&& (*spec
== *path
)) {
409 if ((*spec
== *path
) || (*spec
== '*'))
415 is_partial_path_in_DB(char *srcpath
, char *trgtpath
)
417 if (strstr(srcpath
, trgtpath
) == NULL
) {