2N/A * The contents of this file are subject to the terms of the 2N/A * Common Development and Distribution License (the "License"). 2N/A * You may not use this file except in compliance with the License. 2N/A * See the License for the specific language governing permissions 2N/A * and limitations under the License. 2N/A * When distributing Covered Code, include this CDDL HEADER in each 2N/A * If applicable, add the following below this CDDL HEADER, with the 2N/A * fields enclosed by brackets "[]" replaced with your own identifying 2N/A * information: Portions Copyright [yyyy] [name of copyright owner] 2N/A * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. * The following globals are necessary due to the "walker" function * provided by nftw(). Since there is no way to pass them through to the * walker function, they must be global. * Break the creation of a manifest into two parts: the parent process * generated the data whereas the child process sorts the data. * The processes communicate through the pipe. * Redirect the stdout of this process so it goes into * output_pipe[0]. The output of this process will be read * by the child, which will sort the output. /* Close stdout so the sort in the child proc will complete */ * Redirect the stdin of this process so its read in from * the pipe, which is the parent process in this case. /* Wait for the child proc (the sort) to complete */ * Handle the -R option and sets 'root' to be the absolute path of the * relocatable root. This is useful when the user specifies '-R ../../foo'. * Return code is whether or not the location spec'd by the -R flag is a * First, save the current directory and go to the location * specified with the -R option. /* Failed to change directory, something is wrong.... */ * Save the absolute path of the relocatable root directory. * Now, go back to where we started, necessary for picking up a rules /* Failed to change directory, something is wrong.... */ * Make sure the path returned does not have a trailing /. This * can only happen when the entire pathname is "/". * Since the earlier chdir() succeeded, return success. * This is the worker bee which creates the manifest based upon the command * line options supplied by the user. * NOTE: create_manifest() eventually outputs data to a pipe, which is read in * by the child process. The child process is running output_manifest(), which * is responsible for generating sorted output. /* Loop through every single subtree */ * Check to see if this subtree should have contents * checking turned on or off. * NOTE: The 'compute_chksum' and 'parent_vfs' * are a necessary hack: the variables are used in * walker(), both directly and indirectly. Since * the parameters to walker() are defined by nftw(), * the globals are really a backdoor mechanism. * Walk the subtree and invoke the callback function walker() * Use FTW_ANYERR to get FTW_NS and FTW_DNR entries *and* * to continue past those errors. * walker() must return 0, or the tree walk will stop, * so warning flags must be set through a global. * output_manifest() the child process. It reads in the output from * create_manifest() and sorts it. char *
env[] = {
"LC_CTYPE=C",
"LC_COLLATE=C",
"LC_NUMERIC=C",
NULL};
* Simply run sort and read from the the current stdin, which is really * the output of create_manifest(). * Also, make sure the output is unique, since a given file may be * included by several stanzas. * Callback function for nftw() case FTW_SL:
/* symbolic link, FTW_PHYS */ case FTW_SLN:
/* symbolic link, ~FTW_PHYS */ case FTW_DP:
/* end of directory, FTW_DEPTH */ case FTW_D:
/* enter directory, ~FTW_DEPTH */ case FTW_NS:
/* unstatable file */ case FTW_DNR:
/* unreadable directory */ /* This is the function which really processes the file */ * Since the parameters to walker() are constrained by nftw(), * need to use a global to reflect a WARNING. Sigh. * This is a case of a directory which crosses into a mounted * filesystem of a different type, e.g., UFS -> NFS. * BART should not walk the new filesystem (by specification), so * set this consolidation-private flag so the rest of the subtree * under this directory is not waled. * This file does the per-file evaluation and is run to generate every entry * All output is written to a pipe which is read by the child process, * which is running output_manifest(). default:
ftype =
'-';
break;
/* First, make sure this file should be cataloged */ * Regular files, compute the MD5 checksum and put it into 'last_field' * UNLESS instructed to ignore the checksums. /* default value since the computution failed */ /* Instructed to ignore checksums, just put in a '-' */ * For symbolic links, put the destination of the symbolic link into /* default value since the computation failed */ * Boundary condition: possible for a symlink to point to * nothing [ ln -s '' link_name ]. For this case, set the /* Sanitize 'fname', so its in the proper format for the manifest */ /* Start to build the entry.... */ /* Finish it off based upon whether or not it's a device node */ /* free the memory consumed */ * When creating a manifest, make sure all '?', tabs, space, newline, '/' * and '[' are all properly quoted. Convert them to a "\ooo" where the 'ooo' * represents their octal value. For filesystem objects, as opposed to symlink * targets, also canonicalize the pathname. /* Initialize everything */ * In the case when a relocatable root was used, the relocatable * root should *not* be part of the manifest. * In the case when the '-I' option was used, make sure * the quoted_name starts with a '/'. /* Now walk through 'fname' and build the quoted string */ while ((
ch = *
ip++) != 0) {
/* Quote the following characters */ /* Otherwise, simply append them */ * Function responsible for generating the ACL information for a given * file. Note, the string is put into buffer malloc'd by this function. * It's the responsibility of the caller to free the buffer. This function * should never return a NULL pointer. * description: This routine reads stdin in BUF_SIZE chunks, uses the bits * to update the md5 hash buffer, and outputs the chunks * to stdout. When stdin is exhausted, the hash is computed, * converted to a hexadecimal string, and returned. * returns: The md5 hash of stdin, or NULL if unsuccessful for any reason. /* got some data. Now update hash */ /* done passing through data, calculate hash */ * Used by 'bart create' with the '-I' option. Return each entry into a 'buf' * with the appropriate exit code: '0' for success and '-1' for failure. * Setup this code so it knows whether or not to read sdtin. * Also, if reading from argv, setup the index, "argv_index" /* In this case, no args after '-I', so read stdin */ * Unlike similar code elsewhere, avoid adding a leading * slash for relative pathnames.