usr/src/cmd/bart/create.c
author John.Zolnowsky@Sun.COM
Mon, 10 May 2010 11:04:39 -0700
changeset 12369 c277f6e4bc5b
parent 9298 5ecf9483b3ec
child 13116 4fa15249a57b
permissions -rw-r--r--
6933243 Systemwide bart(1M) manifests do not include data for all files & dirs on systems with zones running
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     1
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     2
 * CDDL HEADER START
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     3
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     4
 * The contents of this file are subject to the terms of the
2812
00077a9dd3fe 6244408 bart manifest does not contain device node information
jc144527
parents: 1420
diff changeset
     5
 * Common Development and Distribution License (the "License").
00077a9dd3fe 6244408 bart manifest does not contain device node information
jc144527
parents: 1420
diff changeset
     6
 * You may not use this file except in compliance with the License.
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     7
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     8
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     9
 * or http://www.opensolaris.org/os/licensing.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    10
 * See the License for the specific language governing permissions
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    11
 * and limitations under the License.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    12
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    13
 * When distributing Covered Code, include this CDDL HEADER in each
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    14
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    15
 * If applicable, add the following below this CDDL HEADER, with the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    16
 * fields enclosed by brackets "[]" replaced with your own identifying
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    17
 * information: Portions Copyright [yyyy] [name of copyright owner]
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    18
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    19
 * CDDL HEADER END
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    20
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    21
/*
12369
c277f6e4bc5b 6933243 Systemwide bart(1M) manifests do not include data for all files & dirs on systems with zones running
John.Zolnowsky@Sun.COM
parents: 9298
diff changeset
    22
 * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    23
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    24
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    25
#include <signal.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    26
#include <unistd.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    27
#include <sys/acl.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    28
#include <sys/statvfs.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    29
#include <sys/wait.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    30
#include "bart.h"
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 0
diff changeset
    31
#include <aclutils.h>
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    32
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    33
static int	sanitize_reloc_root(char *root, size_t bufsize);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    34
static int	create_manifest_filelist(char **argv, char *reloc_root);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    35
static int	create_manifest_rule(char *reloc_root, FILE *rule_fp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    36
static void	output_manifest(void);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    37
static int	eval_file(const char *fname, const struct stat64 *statb);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    38
static char	*sanitized_fname(const char *, boolean_t);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    39
static char	*get_acl_string(const char *fname, const struct stat64 *statb,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    40
    int *err_code);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    41
static int	generate_hash(int fdin, char *hash_str);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    42
static int	read_filelist(char *reloc_root, char **argv, char *buf,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    43
    size_t bufsize);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    44
static int	walker(const char *name, const struct stat64 *sp,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    45
    int type, struct FTW *ftwx);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    46
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    47
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    48
 * The following globals are necessary due to the "walker" function
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    49
 * provided by nftw().  Since there is no way to pass them through to the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    50
 * walker function, they must be global.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    51
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    52
static int		compute_chksum = 1, eval_err = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    53
static struct rule	*subtree_root;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    54
static char		reloc_root[PATH_MAX];
9298
5ecf9483b3ec 6436517 bart needs to be large files aware to support ZFS roots greater than 2TB
William Young <William.Young@Sun.COM>
parents: 2813
diff changeset
    55
static struct statvfs64	parent_vfs;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    56
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    57
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    58
bart_create(int argc, char **argv)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    59
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    60
	boolean_t	filelist_input;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    61
	int		ret, c, output_pipe[2];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    62
	FILE 		*rules_fd = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    63
	pid_t		pid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    64
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    65
	filelist_input = B_FALSE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    66
	reloc_root[0] = '\0';
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    67
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    68
	while ((c = getopt(argc, argv, "Inr:R:")) != EOF) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    69
		switch (c) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    70
		case 'I':
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    71
			if (rules_fd != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    72
				(void) fprintf(stderr, "%s", INPUT_ERR);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    73
				usage();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    74
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    75
			filelist_input = B_TRUE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    76
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    77
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    78
		case 'n':
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    79
			compute_chksum = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    80
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    81
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    82
		case 'r':
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    83
			if (strcmp(optarg, "-") == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    84
				rules_fd = stdin;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    85
			else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    86
				rules_fd = fopen(optarg, "r");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    87
			if (rules_fd == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    88
				perror(optarg);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    89
				usage();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    90
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    91
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    92
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    93
		case 'R':
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    94
			(void) strlcpy(reloc_root, optarg, sizeof (reloc_root));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    95
			ret = sanitize_reloc_root(reloc_root,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    96
			    sizeof (reloc_root));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    97
			if (ret == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    98
				usage();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    99
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   100
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   101
		case '?':
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   102
		default :
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   103
			usage();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   104
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   105
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   106
	argv += optind;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   107
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   108
	if (pipe(output_pipe) < 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   109
		perror("");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   110
		exit(FATAL_EXIT);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   111
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   112
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   113
	pid = fork();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   114
	if (pid < 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   115
		perror(NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   116
		exit(FATAL_EXIT);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   117
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   118
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   119
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   120
	 * Break the creation of a manifest into two parts: the parent process
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   121
	 * generated the data whereas the child process sorts the data.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   122
	 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   123
	 * The processes communicate through the pipe.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   124
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   125
	if (pid > 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   126
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   127
		 * Redirect the stdout of this process so it goes into
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   128
		 * output_pipe[0].  The output of this process will be read
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   129
		 * by the child, which will sort the output.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   130
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   131
		if (dup2(output_pipe[0], STDOUT_FILENO) != STDOUT_FILENO) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   132
			perror(NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   133
			exit(FATAL_EXIT);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   134
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   135
		(void) close(output_pipe[0]);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   136
		(void) close(output_pipe[1]);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   137
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   138
		if (filelist_input == B_TRUE) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   139
			ret = create_manifest_filelist(argv, reloc_root);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   140
		} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   141
			ret = create_manifest_rule(reloc_root, rules_fd);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   142
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   143
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   144
		/* Close stdout so the sort in the child proc will complete */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   145
		(void) fclose(stdout);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   146
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   147
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   148
		 * Redirect the stdin of this process so its read in from
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   149
		 * the pipe, which is the parent process in this case.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   150
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   151
		if (dup2(output_pipe[1], STDIN_FILENO) != STDIN_FILENO) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   152
			perror(NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   153
			exit(FATAL_EXIT);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   154
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   155
		(void) close(output_pipe[0]);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   156
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   157
		output_manifest();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   158
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   159
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   160
	/* Wait for the child proc (the sort) to complete */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   161
	(void) wait(0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   162
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   163
	return (ret);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   164
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   165
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   166
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   167
 * Handle the -R option and sets 'root' to be the absolute path of the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   168
 * relocatable root.  This is useful when the user specifies '-R ../../foo'.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   169
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   170
 * Return code is whether or not the location spec'd by the -R flag is a
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   171
 * directory or not.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   172
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   173
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   174
sanitize_reloc_root(char *root, size_t bufsize)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   175
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   176
	char		pwd[PATH_MAX];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   177
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   178
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   179
	 * First, save the current directory and go to the location
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   180
	 * specified with the -R option.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   181
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   182
	(void) getcwd(pwd, sizeof (pwd));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   183
	if (chdir(root) < 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   184
		/* Failed to change directory, something is wrong.... */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   185
		perror(root);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   186
		return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   187
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   188
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   189
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   190
	 * Save the absolute path of the relocatable root directory.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   191
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   192
	(void) getcwd(root, bufsize);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   193
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   194
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   195
	 * Now, go back to where we started, necessary for picking up a rules
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   196
	 * file.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   197
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   198
	if (chdir(pwd) < 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   199
		/* Failed to change directory, something is wrong.... */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   200
		perror(root);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   201
		return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   202
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   203
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   204
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   205
	 * Make sure the path returned does not have a trailing /. This
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   206
	 * can only happen when the entire pathname is "/".
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   207
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   208
	if (strcmp(root, "/") == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   209
		root[0] = '\0';
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   210
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   211
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   212
	 * Since the earlier chdir() succeeded, return success.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   213
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   214
	return (1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   215
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   216
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   217
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   218
 * This is the worker bee which creates the manifest based upon the command
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   219
 * line options supplied by the user.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   220
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   221
 * NOTE: create_manifest() eventually outputs data to a pipe, which is read in
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   222
 * by the child process.  The child process is running output_manifest(), which
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   223
 * is responsible for generating sorted output.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   224
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   225
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   226
create_manifest_rule(char *reloc_root, FILE *rule_fp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   227
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   228
	struct rule	*root;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   229
	int		ret_status = EXIT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   230
	uint_t		flags;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   231
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   232
	if (compute_chksum)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   233
		flags = ATTR_CONTENTS;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   234
	else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   235
		flags = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   236
	ret_status = read_rules(rule_fp, reloc_root, flags, 1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   237
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   238
	/* Loop through every single subtree */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   239
	for (root = get_first_subtree(); root != NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   240
	    root = get_next_subtree(root)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   241
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   242
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   243
		 * Check to see if this subtree should have contents
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   244
		 * checking turned on or off.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   245
		 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   246
		 * NOTE: The 'compute_chksum' and 'parent_vfs'
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   247
		 * are a necessary hack: the variables are used in
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   248
		 * walker(), both directly and indirectly.  Since
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   249
		 * the parameters to walker() are defined by nftw(),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   250
		 * the globals are really a backdoor mechanism.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   251
		 */
9298
5ecf9483b3ec 6436517 bart needs to be large files aware to support ZFS roots greater than 2TB
William Young <William.Young@Sun.COM>
parents: 2813
diff changeset
   252
		ret_status = statvfs64(root->subtree, &parent_vfs);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   253
		if (ret_status < 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   254
			perror(root->subtree);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   255
			continue;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   256
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   257
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   258
		/*
12369
c277f6e4bc5b 6933243 Systemwide bart(1M) manifests do not include data for all files & dirs on systems with zones running
John.Zolnowsky@Sun.COM
parents: 9298
diff changeset
   259
		 * Walk the subtree and invoke the callback function walker()
c277f6e4bc5b 6933243 Systemwide bart(1M) manifests do not include data for all files & dirs on systems with zones running
John.Zolnowsky@Sun.COM
parents: 9298
diff changeset
   260
		 * Use FTW_ANYERR to get FTW_NS and FTW_DNR entries *and*
c277f6e4bc5b 6933243 Systemwide bart(1M) manifests do not include data for all files & dirs on systems with zones running
John.Zolnowsky@Sun.COM
parents: 9298
diff changeset
   261
		 * to continue past those errors.
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   262
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   263
		subtree_root = root;
12369
c277f6e4bc5b 6933243 Systemwide bart(1M) manifests do not include data for all files & dirs on systems with zones running
John.Zolnowsky@Sun.COM
parents: 9298
diff changeset
   264
		(void) nftw64(root->subtree, &walker, 20, FTW_PHYS|FTW_ANYERR);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   265
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   266
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   267
		 * Ugly but necessary:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   268
		 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   269
		 * walker() must return 0, or the tree walk will stop,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   270
		 * so warning flags must be set through a global.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   271
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   272
		if (eval_err == WARNING_EXIT)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   273
			ret_status = WARNING_EXIT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   274
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   275
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   276
	return (ret_status);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   277
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   278
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   279
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   280
create_manifest_filelist(char **argv, char *reloc_root)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   281
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   282
	int	ret_status = EXIT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   283
	char	input_fname[PATH_MAX];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   284
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   285
	while (read_filelist(reloc_root, argv,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   286
	    input_fname, sizeof (input_fname)) != -1) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   287
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   288
		struct stat64	stat_buf;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   289
		int		ret;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   290
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   291
		ret = lstat64(input_fname, &stat_buf);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   292
		if (ret < 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   293
			ret_status = WARNING_EXIT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   294
			perror(input_fname);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   295
		} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   296
			ret = eval_file(input_fname, &stat_buf);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   297
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   298
			if (ret == WARNING_EXIT)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   299
				ret_status = WARNING_EXIT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   300
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   301
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   302
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   303
	return (ret_status);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   304
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   305
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   306
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   307
 * output_manifest() the child process.  It reads in the output from
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   308
 * create_manifest() and sorts it.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   309
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   310
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   311
output_manifest(void)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   312
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   313
	char	*env[] = {"LC_CTYPE=C", "LC_COLLATE=C", "LC_NUMERIC=C", NULL};
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   314
	time_t		time_val;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   315
	struct tm	*tm;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   316
	char		time_buf[1024];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   317
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   318
	(void) printf("%s", MANIFEST_VER);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   319
	time_val = time((time_t)0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   320
	tm = localtime(&time_val);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   321
	(void) strftime(time_buf, sizeof (time_buf), "%A, %B %d, %Y (%T)", tm);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   322
	(void) printf("! %s\n", time_buf);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   323
	(void) printf("%s", FORMAT_STR);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   324
	(void) fflush(stdout);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   325
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   326
	 * Simply run sort and read from the the current stdin, which is really
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   327
	 * the output of create_manifest().
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   328
	 * Also, make sure the output is unique, since a given file may be
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   329
	 * included by several stanzas.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   330
	 */
2813
c41c468efdef 6408879 /usr/bin/bart create not including all files in manifest for multiple subtrees in a block
rm88369
parents: 2812
diff changeset
   331
	if (execle("/usr/bin/sort", "sort", "-u", NULL, env) < 0) {
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   332
		perror("");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   333
		exit(FATAL_EXIT);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   334
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   335
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   336
	/*NOTREACHED*/
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   337
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   338
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   339
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   340
 * Callback function for nftw()
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   341
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   342
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   343
walker(const char *name, const struct stat64 *sp, int type, struct FTW *ftwx)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   344
{
9298
5ecf9483b3ec 6436517 bart needs to be large files aware to support ZFS roots greater than 2TB
William Young <William.Young@Sun.COM>
parents: 2813
diff changeset
   345
	int			ret;
5ecf9483b3ec 6436517 bart needs to be large files aware to support ZFS roots greater than 2TB
William Young <William.Young@Sun.COM>
parents: 2813
diff changeset
   346
	struct statvfs64	path_vfs;
5ecf9483b3ec 6436517 bart needs to be large files aware to support ZFS roots greater than 2TB
William Young <William.Young@Sun.COM>
parents: 2813
diff changeset
   347
	boolean_t		dir_flag = B_FALSE;
5ecf9483b3ec 6436517 bart needs to be large files aware to support ZFS roots greater than 2TB
William Young <William.Young@Sun.COM>
parents: 2813
diff changeset
   348
	struct rule		*rule;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   349
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   350
	switch (type) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   351
	case FTW_F:	/* file 		*/
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   352
		rule = check_rules(name, 'F');
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   353
		if (rule != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   354
			if (rule->attr_list & ATTR_CONTENTS)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   355
				compute_chksum = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   356
			else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   357
				compute_chksum = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   358
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   359
		break;
12369
c277f6e4bc5b 6933243 Systemwide bart(1M) manifests do not include data for all files & dirs on systems with zones running
John.Zolnowsky@Sun.COM
parents: 9298
diff changeset
   360
	case FTW_SL:	/* symbolic link, FTW_PHYS	*/
c277f6e4bc5b 6933243 Systemwide bart(1M) manifests do not include data for all files & dirs on systems with zones running
John.Zolnowsky@Sun.COM
parents: 9298
diff changeset
   361
	case FTW_SLN:	/* symbolic link, ~FTW_PHYS	*/
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   362
		break;
12369
c277f6e4bc5b 6933243 Systemwide bart(1M) manifests do not include data for all files & dirs on systems with zones running
John.Zolnowsky@Sun.COM
parents: 9298
diff changeset
   363
	case FTW_DP:	/* end of directory, FTW_DEPTH	*/
c277f6e4bc5b 6933243 Systemwide bart(1M) manifests do not include data for all files & dirs on systems with zones running
John.Zolnowsky@Sun.COM
parents: 9298
diff changeset
   364
	case FTW_D:	/* enter directory, ~FTW_DEPTH	*/
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   365
		dir_flag = B_TRUE;
9298
5ecf9483b3ec 6436517 bart needs to be large files aware to support ZFS roots greater than 2TB
William Young <William.Young@Sun.COM>
parents: 2813
diff changeset
   366
		ret = statvfs64(name, &path_vfs);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   367
		if (ret < 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   368
			eval_err = WARNING_EXIT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   369
		break;
12369
c277f6e4bc5b 6933243 Systemwide bart(1M) manifests do not include data for all files & dirs on systems with zones running
John.Zolnowsky@Sun.COM
parents: 9298
diff changeset
   370
	case FTW_NS:	/* unstatable file	*/
c277f6e4bc5b 6933243 Systemwide bart(1M) manifests do not include data for all files & dirs on systems with zones running
John.Zolnowsky@Sun.COM
parents: 9298
diff changeset
   371
		(void) fprintf(stderr, UNKNOWN_FILE, name);
c277f6e4bc5b 6933243 Systemwide bart(1M) manifests do not include data for all files & dirs on systems with zones running
John.Zolnowsky@Sun.COM
parents: 9298
diff changeset
   372
		eval_err = WARNING_EXIT;
c277f6e4bc5b 6933243 Systemwide bart(1M) manifests do not include data for all files & dirs on systems with zones running
John.Zolnowsky@Sun.COM
parents: 9298
diff changeset
   373
		return (0);
c277f6e4bc5b 6933243 Systemwide bart(1M) manifests do not include data for all files & dirs on systems with zones running
John.Zolnowsky@Sun.COM
parents: 9298
diff changeset
   374
	case FTW_DNR:	/* unreadable directory	*/
c277f6e4bc5b 6933243 Systemwide bart(1M) manifests do not include data for all files & dirs on systems with zones running
John.Zolnowsky@Sun.COM
parents: 9298
diff changeset
   375
		(void) fprintf(stderr, CANTLIST_DIR, name);
c277f6e4bc5b 6933243 Systemwide bart(1M) manifests do not include data for all files & dirs on systems with zones running
John.Zolnowsky@Sun.COM
parents: 9298
diff changeset
   376
		eval_err = WARNING_EXIT;
c277f6e4bc5b 6933243 Systemwide bart(1M) manifests do not include data for all files & dirs on systems with zones running
John.Zolnowsky@Sun.COM
parents: 9298
diff changeset
   377
		return (0);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   378
	default:
12369
c277f6e4bc5b 6933243 Systemwide bart(1M) manifests do not include data for all files & dirs on systems with zones running
John.Zolnowsky@Sun.COM
parents: 9298
diff changeset
   379
		(void) fprintf(stderr, INTERNAL_ERR, name);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   380
		eval_err = WARNING_EXIT;
12369
c277f6e4bc5b 6933243 Systemwide bart(1M) manifests do not include data for all files & dirs on systems with zones running
John.Zolnowsky@Sun.COM
parents: 9298
diff changeset
   381
		return (0);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   382
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   383
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   384
	/* This is the function which really processes the file */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   385
	ret = eval_file(name, sp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   386
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   387
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   388
	 * Since the parameters to walker() are constrained by nftw(),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   389
	 * need to use a global to reflect a WARNING.  Sigh.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   390
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   391
	if (ret == WARNING_EXIT)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   392
		eval_err = WARNING_EXIT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   393
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   394
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   395
	 * This is a case of a directory which crosses into a mounted
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   396
	 * filesystem of a different type, e.g., UFS -> NFS.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   397
	 * BART should not walk the new filesystem (by specification), so
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   398
	 * set this consolidation-private flag so the rest of the subtree
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   399
	 * under this directory is not waled.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   400
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   401
	if (dir_flag &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   402
	    (strcmp(parent_vfs.f_basetype, path_vfs.f_basetype) != 0))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   403
		ftwx->quit = FTW_PRUNE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   404
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   405
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   406
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   407
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   408
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   409
 * This file does the per-file evaluation and is run to generate every entry
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   410
 * in the manifest.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   411
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   412
 * All output is written to a pipe which is read by the child process,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   413
 * which is running output_manifest().
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   414
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   415
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   416
eval_file(const char *fname, const struct stat64 *statb)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   417
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   418
	int	fd, ret, err_code, i;
9298
5ecf9483b3ec 6436517 bart needs to be large files aware to support ZFS roots greater than 2TB
William Young <William.Young@Sun.COM>
parents: 2813
diff changeset
   419
	char	last_field[PATH_MAX], ftype, *acl_str;
5ecf9483b3ec 6436517 bart needs to be large files aware to support ZFS roots greater than 2TB
William Young <William.Young@Sun.COM>
parents: 2813
diff changeset
   420
	char	*quoted_name;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   421
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   422
	err_code = EXIT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   423
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   424
	switch (statb->st_mode & S_IFMT) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   425
	/* Regular file */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   426
	case S_IFREG: ftype = 'F'; break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   427
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   428
	/* Directory */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   429
	case S_IFDIR: ftype = 'D'; break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   430
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   431
	/* Block Device */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   432
	case S_IFBLK: ftype = 'B'; break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   433
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   434
	/* Character Device */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   435
	case S_IFCHR: ftype = 'C'; break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   436
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   437
	/* Named Pipe */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   438
	case S_IFIFO: ftype = 'P'; break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   439
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   440
	/* Socket */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   441
	case S_IFSOCK: ftype = 'S'; break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   442
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   443
	/* Door */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   444
	case S_IFDOOR: ftype = 'O'; break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   445
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   446
	/* Symbolic link */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   447
	case S_IFLNK: ftype = 'L'; break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   448
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   449
	default: ftype = '-'; break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   450
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   451
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   452
	/* First, make sure this file should be cataloged */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   453
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   454
	if ((subtree_root != NULL) &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   455
	    (exclude_fname(fname, ftype, subtree_root)))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   456
		return (err_code);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   457
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   458
	for (i = 0; i < PATH_MAX; i++)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   459
		last_field[i] = '\0';
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   460
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   461
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   462
	 * Regular files, compute the MD5 checksum and put it into 'last_field'
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   463
	 * UNLESS instructed to ignore the checksums.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   464
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   465
	if (ftype == 'F') {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   466
		if (compute_chksum) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   467
			fd = open(fname, O_RDONLY|O_LARGEFILE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   468
			if (fd < 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   469
				err_code = WARNING_EXIT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   470
				perror(fname);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   471
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   472
				/* default value since the computution failed */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   473
				(void) strcpy(last_field, "-");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   474
			} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   475
				if (generate_hash(fd, last_field) != 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   476
					err_code = WARNING_EXIT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   477
					(void) fprintf(stderr, CONTENTS_WARN,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   478
					    fname);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   479
					(void) strcpy(last_field, "-");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   480
				}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   481
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   482
			(void) close(fd);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   483
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   484
		/* Instructed to ignore checksums, just put in a '-' */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   485
		else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   486
			(void) strcpy(last_field, "-");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   487
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   488
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   489
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   490
	 * For symbolic links, put the destination of the symbolic link into
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   491
	 * 'last_field'
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   492
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   493
	if (ftype == 'L') {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   494
		ret = readlink(fname, last_field, sizeof (last_field));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   495
		if (ret < 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   496
			err_code = WARNING_EXIT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   497
			perror(fname);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   498
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   499
			/* default value since the computation failed */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   500
			(void) strcpy(last_field, "-");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   501
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   502
		else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   503
			(void) strlcpy(last_field,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   504
			    sanitized_fname(last_field, B_FALSE),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   505
			    sizeof (last_field));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   506
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   507
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   508
		 * Boundary condition: possible for a symlink to point to
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   509
		 * nothing [ ln -s '' link_name ].  For this case, set the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   510
		 * destination to "\000".
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   511
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   512
		if (strlen(last_field) == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   513
			(void) strcpy(last_field, "\\000");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   514
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   515
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   516
	acl_str = get_acl_string(fname, statb, &err_code);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   517
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   518
	/* Sanitize 'fname', so its in the proper format for the manifest */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   519
	quoted_name = sanitized_fname(fname, B_TRUE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   520
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   521
	/* Start to build the entry.... */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   522
	(void) printf("%s %c %d %o %s %x %d %d", quoted_name, ftype,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   523
	    (int)statb->st_size, (int)statb->st_mode, acl_str,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   524
	    (int)statb->st_mtime, (int)statb->st_uid, (int)statb->st_gid);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   525
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   526
	/* Finish it off based upon whether or not it's a device node */
2812
00077a9dd3fe 6244408 bart manifest does not contain device node information
jc144527
parents: 1420
diff changeset
   527
	if ((ftype == 'B') || (ftype == 'C'))
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   528
		(void) printf(" %x\n", (int)statb->st_rdev);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   529
	else if (strlen(last_field) > 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   530
		(void) printf(" %s\n", last_field);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   531
	else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   532
		(void) printf("\n");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   533
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   534
	/* free the memory consumed */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   535
	free(acl_str);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   536
	free(quoted_name);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   537
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   538
	return (err_code);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   539
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   540
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   541
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   542
 * When creating a manifest, make sure all '?', tabs, space, newline, '/'
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   543
 * and '[' are all properly quoted.  Convert them to a "\ooo" where the 'ooo'
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   544
 * represents their octal value. For filesystem objects, as opposed to symlink
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   545
 * targets, also canonicalize the pathname.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   546
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   547
static char *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   548
sanitized_fname(const char *fname, boolean_t canon_path)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   549
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   550
	const char *ip;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   551
	unsigned char ch;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   552
	char *op, *quoted_name;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   553
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   554
	/* Initialize everything */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   555
	quoted_name = safe_calloc((4 * PATH_MAX) + 1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   556
	ip = fname;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   557
	op = quoted_name;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   558
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   559
	if (canon_path) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   560
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   561
		 * In the case when a relocatable root was used, the relocatable
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   562
		 * root should *not* be part of the manifest.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   563
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   564
		ip += strlen(reloc_root);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   565
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   566
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   567
		 * In the case when the '-I' option was used, make sure
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   568
		 * the quoted_name starts with a '/'.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   569
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   570
		if (*ip != '/')
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   571
			*op++ = '/';
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   572
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   573
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   574
	/* Now walk through 'fname' and build the quoted string */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   575
	while ((ch = *ip++) != 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   576
		switch (ch) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   577
		/* Quote the following characters */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   578
		case ' ':
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   579
		case '*':
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   580
		case '\n':
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   581
		case '?':
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   582
		case '[':
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   583
		case '\\':
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   584
		case '\t':
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   585
			op += sprintf(op, "\\%.3o", (unsigned char)ch);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   586
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   587
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   588
		/* Otherwise, simply append them */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   589
		default:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   590
			*op++ = ch;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   591
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   592
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   593
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   594
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   595
	*op = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   596
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   597
	return (quoted_name);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   598
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   599
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   600
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   601
 * Function responsible for generating the ACL information for a given
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   602
 * file.  Note, the string is put into buffer malloc'd by this function.
9298
5ecf9483b3ec 6436517 bart needs to be large files aware to support ZFS roots greater than 2TB
William Young <William.Young@Sun.COM>
parents: 2813
diff changeset
   603
 * It's the responsibility of the caller to free the buffer.  This function
5ecf9483b3ec 6436517 bart needs to be large files aware to support ZFS roots greater than 2TB
William Young <William.Young@Sun.COM>
parents: 2813
diff changeset
   604
 * should never return a NULL pointer.
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   605
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   606
static char *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   607
get_acl_string(const char *fname, const struct stat64 *statb, int *err_code)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   608
{
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 0
diff changeset
   609
	acl_t		*aclp;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 0
diff changeset
   610
	char		*acltext;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 0
diff changeset
   611
	int		error;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   612
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   613
	if (S_ISLNK(statb->st_mode)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   614
		return (safe_strdup("-"));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   615
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   616
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 0
diff changeset
   617
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 0
diff changeset
   618
	 *  Include trivial acl's
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 0
diff changeset
   619
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 0
diff changeset
   620
	error = acl_get(fname, 0, &aclp);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   621
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 0
diff changeset
   622
	if (error != 0) {
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   623
		*err_code = WARNING_EXIT;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 0
diff changeset
   624
		(void) fprintf(stderr, "%s: %s\n", fname, acl_strerror(error));
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   625
		return (safe_strdup("-"));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 0
diff changeset
   626
	} else {
1420
4cb3c26a37e0 PSARC/2006/043 ls -V
marks
parents: 789
diff changeset
   627
		acltext = acl_totext(aclp, 0);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 0
diff changeset
   628
		acl_free(aclp);
9298
5ecf9483b3ec 6436517 bart needs to be large files aware to support ZFS roots greater than 2TB
William Young <William.Young@Sun.COM>
parents: 2813
diff changeset
   629
		if (acltext == NULL)
5ecf9483b3ec 6436517 bart needs to be large files aware to support ZFS roots greater than 2TB
William Young <William.Young@Sun.COM>
parents: 2813
diff changeset
   630
			return (safe_strdup("-"));
5ecf9483b3ec 6436517 bart needs to be large files aware to support ZFS roots greater than 2TB
William Young <William.Young@Sun.COM>
parents: 2813
diff changeset
   631
		else
5ecf9483b3ec 6436517 bart needs to be large files aware to support ZFS roots greater than 2TB
William Young <William.Young@Sun.COM>
parents: 2813
diff changeset
   632
			return (acltext);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   633
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   634
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   635
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   636
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   637
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   638
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   639
 * description:	This routine reads stdin in BUF_SIZE chunks, uses the bits
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   640
 *		to update the md5 hash buffer, and outputs the chunks
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   641
 *		to stdout.  When stdin is exhausted, the hash is computed,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   642
 *		converted to a hexadecimal string, and returned.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   643
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   644
 * returns:	The md5 hash of stdin, or NULL if unsuccessful for any reason.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   645
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   646
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   647
generate_hash(int fdin, char *hash_str)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   648
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   649
	unsigned char buf[BUF_SIZE];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   650
	unsigned char hash[MD5_DIGEST_LENGTH];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   651
	int i, amtread;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   652
	MD5_CTX ctx;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   653
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   654
	MD5Init(&ctx);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   655
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   656
	for (;;) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   657
		amtread = read(fdin, buf, sizeof (buf));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   658
		if (amtread == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   659
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   660
		if (amtread <  0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   661
			return (1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   662
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   663
		/* got some data.  Now update hash */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   664
		MD5Update(&ctx, buf, amtread);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   665
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   666
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   667
	/* done passing through data, calculate hash */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   668
	MD5Final(hash, &ctx);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   669
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   670
	for (i = 0; i < MD5_DIGEST_LENGTH; i++)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   671
		(void) sprintf(hash_str + (i*2), "%2.2x", hash[i]);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   672
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   673
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   674
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   675
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   676
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   677
 * Used by 'bart create' with the '-I' option.  Return each entry into a 'buf'
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   678
 * with the appropriate exit code: '0' for success and '-1' for failure.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   679
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   680
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   681
read_filelist(char *reloc_root, char **argv, char *buf, size_t bufsize)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   682
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   683
	static int		argv_index = -1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   684
	static boolean_t	read_stdinput = B_FALSE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   685
	char			temp_buf[PATH_MAX];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   686
	char 			*cp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   687
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   688
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   689
	 * INITIALIZATION:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   690
	 * Setup this code so it knows whether or not to read sdtin.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   691
	 * Also, if reading from argv, setup the index, "argv_index"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   692
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   693
	if (argv_index == -1) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   694
		argv_index = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   695
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   696
		/* In this case, no args after '-I', so read stdin */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   697
		if (argv[0] == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   698
			read_stdinput = B_TRUE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   699
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   700
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   701
	buf[0] = '\0';
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   702
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   703
	if (read_stdinput) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   704
		if (fgets(temp_buf, PATH_MAX, stdin) == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   705
			return (-1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   706
		cp = strtok(temp_buf, "\n");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   707
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   708
		cp = argv[argv_index++];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   709
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   710
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   711
	if (cp == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   712
		return (-1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   713
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   714
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   715
	 * Unlike similar code elsewhere, avoid adding a leading
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   716
	 * slash for relative pathnames.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   717
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   718
	(void) snprintf(buf, bufsize,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   719
	    (reloc_root[0] == '\0' || cp[0] == '/') ? "%s%s" : "%s/%s",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   720
	    reloc_root, cp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   721
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   722
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   723
}