xref: /onnv-gate/usr/src/cmd/svc/mfstscan/mfstscan.c (revision 13112:e0ee41527b6e)
10Sstevel@tonic-gate /*
20Sstevel@tonic-gate  * CDDL HEADER START
30Sstevel@tonic-gate  *
40Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
51864Sbustos  * Common Development and Distribution License (the "License").
61864Sbustos  * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate  *
80Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate  * See the License for the specific language governing permissions
110Sstevel@tonic-gate  * and limitations under the License.
120Sstevel@tonic-gate  *
130Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate  *
190Sstevel@tonic-gate  * CDDL HEADER END
200Sstevel@tonic-gate  */
21*13112STony.Q.Nguyen@oracle.com 
220Sstevel@tonic-gate /*
23*13112STony.Q.Nguyen@oracle.com  * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
240Sstevel@tonic-gate  */
250Sstevel@tonic-gate 
260Sstevel@tonic-gate #include <sys/types.h>
270Sstevel@tonic-gate 
2811996SThomas.Whitten@Sun.COM #include <errno.h>
2911996SThomas.Whitten@Sun.COM #include <fcntl.h>
300Sstevel@tonic-gate #include <libintl.h>
31*13112STony.Q.Nguyen@oracle.com #include <libscf.h>
320Sstevel@tonic-gate #include <libuutil.h>
330Sstevel@tonic-gate #include <locale.h>
340Sstevel@tonic-gate #include <stdio.h>
350Sstevel@tonic-gate #include <stdlib.h>
360Sstevel@tonic-gate #include <string.h>
3711996SThomas.Whitten@Sun.COM #include <sys/stat.h>
380Sstevel@tonic-gate #include <unistd.h>
390Sstevel@tonic-gate 
4011996SThomas.Whitten@Sun.COM #include "manifest_find.h"
410Sstevel@tonic-gate #include "manifest_hash.h"
420Sstevel@tonic-gate 
430Sstevel@tonic-gate #define	MAX_DEPTH	24
440Sstevel@tonic-gate 
450Sstevel@tonic-gate /*
460Sstevel@tonic-gate  * mfstscan - service manifest change detection utility
470Sstevel@tonic-gate  *
480Sstevel@tonic-gate  * mfstscan walks the given filesystem hierarchies, and reports those manifests
490Sstevel@tonic-gate  * with changed or absent hash entries.  Manifests are expected to end with a
500Sstevel@tonic-gate  * .xml suffix--other files will be ignored.
510Sstevel@tonic-gate  */
520Sstevel@tonic-gate 
530Sstevel@tonic-gate static void
usage()540Sstevel@tonic-gate usage()
550Sstevel@tonic-gate {
560Sstevel@tonic-gate 	(void) fprintf(stderr, gettext("Usage: %s [-t] path ...\n"),
570Sstevel@tonic-gate 	    uu_getpname());
580Sstevel@tonic-gate 	exit(UU_EXIT_USAGE);
590Sstevel@tonic-gate }
600Sstevel@tonic-gate 
610Sstevel@tonic-gate int
main(int argc,char * argv[])620Sstevel@tonic-gate main(int argc, char *argv[])
630Sstevel@tonic-gate {
6411996SThomas.Whitten@Sun.COM 	manifest_info_t **entry;
6511996SThomas.Whitten@Sun.COM 	manifest_info_t **manifests;
66*13112STony.Q.Nguyen@oracle.com 	scf_handle_t *hndl = NULL;
670Sstevel@tonic-gate 	int i;
680Sstevel@tonic-gate 	int paths_walked = 0;
690Sstevel@tonic-gate 	struct stat sb;
7011996SThomas.Whitten@Sun.COM 	int status;
7111996SThomas.Whitten@Sun.COM 	int tflag = 0;
720Sstevel@tonic-gate 
730Sstevel@tonic-gate 	(void) uu_setpname(argv[0]);
740Sstevel@tonic-gate 
750Sstevel@tonic-gate 	while ((i = getopt(argc, argv, "t")) != -1) {
760Sstevel@tonic-gate 		switch (i) {
770Sstevel@tonic-gate 		case 't':
780Sstevel@tonic-gate 			tflag = 1;
790Sstevel@tonic-gate 			paths_walked = 1;
800Sstevel@tonic-gate 			break;
810Sstevel@tonic-gate 		case '?':
820Sstevel@tonic-gate 		default:
830Sstevel@tonic-gate 			usage();
840Sstevel@tonic-gate 			/*NOTREACHED*/
850Sstevel@tonic-gate 		}
860Sstevel@tonic-gate 	}
870Sstevel@tonic-gate 
880Sstevel@tonic-gate 	if (optind >= argc)
890Sstevel@tonic-gate 		usage();
900Sstevel@tonic-gate 
91*13112STony.Q.Nguyen@oracle.com 	if ((hndl = scf_handle_create(SCF_VERSION)) == NULL)
92*13112STony.Q.Nguyen@oracle.com 		uu_die(gettext("Unexpected libscf error: %s.  Exiting.\n"),
93*13112STony.Q.Nguyen@oracle.com 		    scf_strerror(scf_error()));
94*13112STony.Q.Nguyen@oracle.com 
95*13112STony.Q.Nguyen@oracle.com 	if (scf_handle_bind(hndl) != SCF_SUCCESS)
96*13112STony.Q.Nguyen@oracle.com 		uu_die(gettext("Couldn't bind to svc.configd.\n"));
97*13112STony.Q.Nguyen@oracle.com 
980Sstevel@tonic-gate 	for (i = optind; i < argc; i++) {
990Sstevel@tonic-gate 		if (tflag) {
1007475SPhilippe.Jung@Sun.COM 			char *pname = mhash_filename_to_propname(argv[i],
1017475SPhilippe.Jung@Sun.COM 			    B_FALSE);
1021864Sbustos 
1031864Sbustos 			if (pname != NULL)
1041864Sbustos 				(void) puts(pname);
1051864Sbustos 			else
1061864Sbustos 				uu_warn(gettext("cannot resolve pathname "
1071864Sbustos 				    "for %s"), argv[i]);
1081864Sbustos 
1090Sstevel@tonic-gate 			continue;
1100Sstevel@tonic-gate 		}
1110Sstevel@tonic-gate 
1120Sstevel@tonic-gate 		if (stat(argv[i], &sb) == -1) {
1130Sstevel@tonic-gate 			uu_warn(gettext("cannot stat %s"), argv[i]);
1140Sstevel@tonic-gate 			continue;
1150Sstevel@tonic-gate 		}
1160Sstevel@tonic-gate 
117*13112STony.Q.Nguyen@oracle.com 		status = find_manifests(hndl, argv[i], &manifests,
11811996SThomas.Whitten@Sun.COM 		    CHECKHASH|CHECKEXT);
11911996SThomas.Whitten@Sun.COM 		if (status < 0) {
1200Sstevel@tonic-gate 			uu_warn(gettext("file tree walk of %s encountered "
12111996SThomas.Whitten@Sun.COM 			    "error.  %s\n"), argv[i], strerror(errno));
12211996SThomas.Whitten@Sun.COM 		} else {
1230Sstevel@tonic-gate 			paths_walked++;
12411996SThomas.Whitten@Sun.COM 			if (manifests != NULL) {
12511996SThomas.Whitten@Sun.COM 				for (entry = manifests;
12611996SThomas.Whitten@Sun.COM 				    *entry != NULL;
12711996SThomas.Whitten@Sun.COM 				    entry++) {
12811996SThomas.Whitten@Sun.COM 					(void) printf("%s\n",
12911996SThomas.Whitten@Sun.COM 					    (*entry)->mi_path);
13011996SThomas.Whitten@Sun.COM 				}
13111996SThomas.Whitten@Sun.COM 				free_manifest_array(manifests);
13211996SThomas.Whitten@Sun.COM 			}
13311996SThomas.Whitten@Sun.COM 		}
1340Sstevel@tonic-gate 
13511996SThomas.Whitten@Sun.COM 	}
1360Sstevel@tonic-gate 
1370Sstevel@tonic-gate 	if (!paths_walked)
1380Sstevel@tonic-gate 		uu_die(gettext("no paths walked\n"));
1390Sstevel@tonic-gate 
140*13112STony.Q.Nguyen@oracle.com 	if (hndl != NULL) {
141*13112STony.Q.Nguyen@oracle.com 		(void) scf_handle_unbind(hndl);
142*13112STony.Q.Nguyen@oracle.com 		(void) scf_handle_destroy(hndl);
143*13112STony.Q.Nguyen@oracle.com 	}
144*13112STony.Q.Nguyen@oracle.com 
1450Sstevel@tonic-gate 	return (0);
1460Sstevel@tonic-gate }
147