9444c26f4faabda140242c3986089704c4073cedTom Whitten/*
9444c26f4faabda140242c3986089704c4073cedTom Whitten * CDDL HEADER START
9444c26f4faabda140242c3986089704c4073cedTom Whitten *
9444c26f4faabda140242c3986089704c4073cedTom Whitten * The contents of this file are subject to the terms of the
9444c26f4faabda140242c3986089704c4073cedTom Whitten * Common Development and Distribution License (the "License").
9444c26f4faabda140242c3986089704c4073cedTom Whitten * You may not use this file except in compliance with the License.
9444c26f4faabda140242c3986089704c4073cedTom Whitten *
9444c26f4faabda140242c3986089704c4073cedTom Whitten * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9444c26f4faabda140242c3986089704c4073cedTom Whitten * or http://www.opensolaris.org/os/licensing.
9444c26f4faabda140242c3986089704c4073cedTom Whitten * See the License for the specific language governing permissions
9444c26f4faabda140242c3986089704c4073cedTom Whitten * and limitations under the License.
9444c26f4faabda140242c3986089704c4073cedTom Whitten *
9444c26f4faabda140242c3986089704c4073cedTom Whitten * When distributing Covered Code, include this CDDL HEADER in each
9444c26f4faabda140242c3986089704c4073cedTom Whitten * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
9444c26f4faabda140242c3986089704c4073cedTom Whitten * If applicable, add the following below this CDDL HEADER, with the
9444c26f4faabda140242c3986089704c4073cedTom Whitten * fields enclosed by brackets "[]" replaced with your own identifying
9444c26f4faabda140242c3986089704c4073cedTom Whitten * information: Portions Copyright [yyyy] [name of copyright owner]
9444c26f4faabda140242c3986089704c4073cedTom Whitten *
9444c26f4faabda140242c3986089704c4073cedTom Whitten * CDDL HEADER END
9444c26f4faabda140242c3986089704c4073cedTom Whitten */
9444c26f4faabda140242c3986089704c4073cedTom Whitten
9444c26f4faabda140242c3986089704c4073cedTom Whitten/*
adfc3118ca8c6b541b6a93d4bc24583eb4ebd73dTruong Nguyen * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
9444c26f4faabda140242c3986089704c4073cedTom Whitten */
9444c26f4faabda140242c3986089704c4073cedTom Whitten
9444c26f4faabda140242c3986089704c4073cedTom Whitten/*
9444c26f4faabda140242c3986089704c4073cedTom Whitten * The primary role of this file is to obtain a list of manifests that are
9444c26f4faabda140242c3986089704c4073cedTom Whitten * located in a specified directory or one of its subdirectories. The
9444c26f4faabda140242c3986089704c4073cedTom Whitten * find_manifests() function provides this service, and
9444c26f4faabda140242c3986089704c4073cedTom Whitten * free_manifest_array() is used to free the memory associated with the
9444c26f4faabda140242c3986089704c4073cedTom Whitten * returned list.
9444c26f4faabda140242c3986089704c4073cedTom Whitten *
9444c26f4faabda140242c3986089704c4073cedTom Whitten * The find_manifests() function can return an array consisting of all the
9444c26f4faabda140242c3986089704c4073cedTom Whitten * .xml files in the directory and its subdirectories. Alternatively,
9444c26f4faabda140242c3986089704c4073cedTom Whitten * find_manifests() can be asked to only return new manifests based on the
9444c26f4faabda140242c3986089704c4073cedTom Whitten * return of mhash_test_file(). The list that is returned is an array of
9444c26f4faabda140242c3986089704c4073cedTom Whitten * pointers to manifest_info structures.
9444c26f4faabda140242c3986089704c4073cedTom Whitten *
9444c26f4faabda140242c3986089704c4073cedTom Whitten * Implementation Notes:
9444c26f4faabda140242c3986089704c4073cedTom Whitten * ====================
9444c26f4faabda140242c3986089704c4073cedTom Whitten * This module makes use of the nftw(3C) function to scan the directory.
9444c26f4faabda140242c3986089704c4073cedTom Whitten * nftw() calls a processing function for every file that it finds.
9444c26f4faabda140242c3986089704c4073cedTom Whitten * Unfortunately, nftw does not allow us to pass in any structure pointers
9444c26f4faabda140242c3986089704c4073cedTom Whitten * to the processing function, and that makes it hard to accumulate a list.
9444c26f4faabda140242c3986089704c4073cedTom Whitten * Thus, we will use the thread specific data area to hold data that must
9444c26f4faabda140242c3986089704c4073cedTom Whitten * be retained between calls to the processing function. This will allow
9444c26f4faabda140242c3986089704c4073cedTom Whitten * this module to be used in multi-threaded applications if the need
9444c26f4faabda140242c3986089704c4073cedTom Whitten * arises.
9444c26f4faabda140242c3986089704c4073cedTom Whitten */
9444c26f4faabda140242c3986089704c4073cedTom Whitten
9444c26f4faabda140242c3986089704c4073cedTom Whitten#include <assert.h>
9444c26f4faabda140242c3986089704c4073cedTom Whitten#include <errno.h>
9444c26f4faabda140242c3986089704c4073cedTom Whitten#include <ftw.h>
9444c26f4faabda140242c3986089704c4073cedTom Whitten#include <libscf.h>
9444c26f4faabda140242c3986089704c4073cedTom Whitten#include <libuutil.h>
9444c26f4faabda140242c3986089704c4073cedTom Whitten#include <pthread.h>
9444c26f4faabda140242c3986089704c4073cedTom Whitten#include <stdlib.h>
9444c26f4faabda140242c3986089704c4073cedTom Whitten#include <string.h>
9444c26f4faabda140242c3986089704c4073cedTom Whitten#include "manifest_find.h"
9444c26f4faabda140242c3986089704c4073cedTom Whitten#include "manifest_hash.h"
9444c26f4faabda140242c3986089704c4073cedTom Whitten
9444c26f4faabda140242c3986089704c4073cedTom Whitten#define MAX_DEPTH 24
9444c26f4faabda140242c3986089704c4073cedTom Whitten
9444c26f4faabda140242c3986089704c4073cedTom Whitten/* Thread specific data */
9444c26f4faabda140242c3986089704c4073cedTom Whittentypedef struct mftsd {
9444c26f4faabda140242c3986089704c4073cedTom Whitten manifest_info_t ** tsd_array; /* Array of manifest_info structs */
9444c26f4faabda140242c3986089704c4073cedTom Whitten int tsd_count; /* Number items in list */
9444c26f4faabda140242c3986089704c4073cedTom Whitten int tsd_max; /* Number of pointers allocated */
9444c26f4faabda140242c3986089704c4073cedTom Whitten /* at tsd_array. */
9444c26f4faabda140242c3986089704c4073cedTom Whitten int tsd_flags; /* Check flags for hash and extension */
9444c26f4faabda140242c3986089704c4073cedTom Whitten scf_handle_t *tsd_hndl; /* Handle for libscf. */
9444c26f4faabda140242c3986089704c4073cedTom Whitten} mftsd_t;
9444c26f4faabda140242c3986089704c4073cedTom Whitten
9444c26f4faabda140242c3986089704c4073cedTom Whittenstatic pthread_key_t tsd_key = PTHREAD_ONCE_KEY_NP;
9444c26f4faabda140242c3986089704c4073cedTom Whitten
9444c26f4faabda140242c3986089704c4073cedTom Whitten/*
9444c26f4faabda140242c3986089704c4073cedTom Whitten * Add the manifest info consisting of filename (fn), hash property name
9444c26f4faabda140242c3986089704c4073cedTom Whitten * (pname) and hash to the array at tsd_array. If necessary, realloc()
9444c26f4faabda140242c3986089704c4073cedTom Whitten * will be called to increase the size of the buffer at tsd_array.
9444c26f4faabda140242c3986089704c4073cedTom Whitten *
9444c26f4faabda140242c3986089704c4073cedTom Whitten * Returns 0 on success and -1 on failure. If a failure occurs, errno will
9444c26f4faabda140242c3986089704c4073cedTom Whitten * be set.
9444c26f4faabda140242c3986089704c4073cedTom Whitten */
9444c26f4faabda140242c3986089704c4073cedTom Whittenstatic int
9444c26f4faabda140242c3986089704c4073cedTom Whittenadd_pointer(mftsd_t *tsdp, const char *fn, const char *pname, uchar_t *hash)
9444c26f4faabda140242c3986089704c4073cedTom Whitten{
9444c26f4faabda140242c3986089704c4073cedTom Whitten manifest_info_t *info;
9444c26f4faabda140242c3986089704c4073cedTom Whitten manifest_info_t **newblock;
9444c26f4faabda140242c3986089704c4073cedTom Whitten int new_max;
9444c26f4faabda140242c3986089704c4073cedTom Whitten
9444c26f4faabda140242c3986089704c4073cedTom Whitten if (tsdp->tsd_count >= (tsdp->tsd_max - 1)) {
9444c26f4faabda140242c3986089704c4073cedTom Whitten /* Need more memory. */
9444c26f4faabda140242c3986089704c4073cedTom Whitten new_max = (tsdp->tsd_max == 0) ? 16 : 2 * tsdp->tsd_max;
9444c26f4faabda140242c3986089704c4073cedTom Whitten newblock = realloc(tsdp->tsd_array,
9444c26f4faabda140242c3986089704c4073cedTom Whitten new_max * sizeof (*tsdp->tsd_array));
9444c26f4faabda140242c3986089704c4073cedTom Whitten if (newblock == NULL)
9444c26f4faabda140242c3986089704c4073cedTom Whitten return (-1);
9444c26f4faabda140242c3986089704c4073cedTom Whitten tsdp->tsd_array = newblock;
9444c26f4faabda140242c3986089704c4073cedTom Whitten /* NULL terminate list in case allocations fail below. */
9444c26f4faabda140242c3986089704c4073cedTom Whitten *(tsdp->tsd_array + tsdp->tsd_count) = NULL;
9444c26f4faabda140242c3986089704c4073cedTom Whitten tsdp->tsd_max = new_max;
9444c26f4faabda140242c3986089704c4073cedTom Whitten }
9444c26f4faabda140242c3986089704c4073cedTom Whitten info = uu_zalloc(sizeof (*info));
9444c26f4faabda140242c3986089704c4073cedTom Whitten if (info == NULL) {
9444c26f4faabda140242c3986089704c4073cedTom Whitten errno = ENOMEM;
9444c26f4faabda140242c3986089704c4073cedTom Whitten return (-1);
9444c26f4faabda140242c3986089704c4073cedTom Whitten }
9444c26f4faabda140242c3986089704c4073cedTom Whitten info->mi_path = uu_strdup(fn);
9444c26f4faabda140242c3986089704c4073cedTom Whitten if (info->mi_path == NULL) {
9444c26f4faabda140242c3986089704c4073cedTom Whitten uu_free(info);
9444c26f4faabda140242c3986089704c4073cedTom Whitten errno = ENOMEM;
9444c26f4faabda140242c3986089704c4073cedTom Whitten return (-1);
9444c26f4faabda140242c3986089704c4073cedTom Whitten }
9444c26f4faabda140242c3986089704c4073cedTom Whitten info->mi_prop = pname;
9444c26f4faabda140242c3986089704c4073cedTom Whitten if (hash != NULL)
9444c26f4faabda140242c3986089704c4073cedTom Whitten (void) memcpy(info->mi_hash, hash, MHASH_SIZE);
9444c26f4faabda140242c3986089704c4073cedTom Whitten *(tsdp->tsd_array + tsdp->tsd_count) = info;
9444c26f4faabda140242c3986089704c4073cedTom Whitten tsdp->tsd_count++;
9444c26f4faabda140242c3986089704c4073cedTom Whitten
9444c26f4faabda140242c3986089704c4073cedTom Whitten /* NULL terminate the list. */
9444c26f4faabda140242c3986089704c4073cedTom Whitten *(tsdp->tsd_array + tsdp->tsd_count) = NULL;
9444c26f4faabda140242c3986089704c4073cedTom Whitten
9444c26f4faabda140242c3986089704c4073cedTom Whitten return (0);
9444c26f4faabda140242c3986089704c4073cedTom Whitten}
9444c26f4faabda140242c3986089704c4073cedTom Whitten
9444c26f4faabda140242c3986089704c4073cedTom Whitten/*
9444c26f4faabda140242c3986089704c4073cedTom Whitten * If necessary initialize the thread specific data key at tsd_key, and
9444c26f4faabda140242c3986089704c4073cedTom Whitten * allocate a mftsd_t structure to hold our thread specific data. Upon
9444c26f4faabda140242c3986089704c4073cedTom Whitten * success, the address the thread specific data is returned. On failure,
9444c26f4faabda140242c3986089704c4073cedTom Whitten * NULL is returned and errno is set.
9444c26f4faabda140242c3986089704c4073cedTom Whitten */
9444c26f4faabda140242c3986089704c4073cedTom Whittenstatic mftsd_t *
9444c26f4faabda140242c3986089704c4073cedTom Whittenget_thread_specific_data()
9444c26f4faabda140242c3986089704c4073cedTom Whitten{
9444c26f4faabda140242c3986089704c4073cedTom Whitten mftsd_t *tsdp;
9444c26f4faabda140242c3986089704c4073cedTom Whitten
9444c26f4faabda140242c3986089704c4073cedTom Whitten if (pthread_key_create_once_np(&tsd_key, NULL) != 0)
9444c26f4faabda140242c3986089704c4073cedTom Whitten return (NULL);
9444c26f4faabda140242c3986089704c4073cedTom Whitten tsdp = (mftsd_t *)pthread_getspecific(tsd_key);
9444c26f4faabda140242c3986089704c4073cedTom Whitten if (tsdp == NULL) {
9444c26f4faabda140242c3986089704c4073cedTom Whitten /*
9444c26f4faabda140242c3986089704c4073cedTom Whitten * First time for this thread. We need to allocate memory
9444c26f4faabda140242c3986089704c4073cedTom Whitten * for our thread specific data.
9444c26f4faabda140242c3986089704c4073cedTom Whitten */
9444c26f4faabda140242c3986089704c4073cedTom Whitten tsdp = uu_zalloc(sizeof (*tsdp));
9444c26f4faabda140242c3986089704c4073cedTom Whitten if (tsdp == NULL) {
9444c26f4faabda140242c3986089704c4073cedTom Whitten errno = ENOMEM;
9444c26f4faabda140242c3986089704c4073cedTom Whitten return (NULL);
9444c26f4faabda140242c3986089704c4073cedTom Whitten }
9444c26f4faabda140242c3986089704c4073cedTom Whitten errno = pthread_setspecific(tsd_key, tsdp);
9444c26f4faabda140242c3986089704c4073cedTom Whitten if (errno != 0) {
9444c26f4faabda140242c3986089704c4073cedTom Whitten /*
9444c26f4faabda140242c3986089704c4073cedTom Whitten * EINVAL means that our key is invalid, which
9444c26f4faabda140242c3986089704c4073cedTom Whitten * would be a coding error.
9444c26f4faabda140242c3986089704c4073cedTom Whitten */
9444c26f4faabda140242c3986089704c4073cedTom Whitten assert(errno != EINVAL);
9444c26f4faabda140242c3986089704c4073cedTom Whitten return (NULL);
9444c26f4faabda140242c3986089704c4073cedTom Whitten }
9444c26f4faabda140242c3986089704c4073cedTom Whitten }
9444c26f4faabda140242c3986089704c4073cedTom Whitten return (tsdp);
9444c26f4faabda140242c3986089704c4073cedTom Whitten}
9444c26f4faabda140242c3986089704c4073cedTom Whitten
9444c26f4faabda140242c3986089704c4073cedTom Whitten/*
9444c26f4faabda140242c3986089704c4073cedTom Whitten * This function is called by nftw(3C) every time that it finds an object
9444c26f4faabda140242c3986089704c4073cedTom Whitten * in a directory of interest. If the object is a file, process() checks
adfc3118ca8c6b541b6a93d4bc24583eb4ebd73dTruong Nguyen * to see if it is a service bundle file by insuring that it has a .xml
9444c26f4faabda140242c3986089704c4073cedTom Whitten * extension.
9444c26f4faabda140242c3986089704c4073cedTom Whitten *
adfc3118ca8c6b541b6a93d4bc24583eb4ebd73dTruong Nguyen * If the file is a service bundle file, and the CHECKHASH flag is set process()
adfc3118ca8c6b541b6a93d4bc24583eb4ebd73dTruong Nguyen * calls mhash_test_file() to see if it is a new bundle. Bundle file data
adfc3118ca8c6b541b6a93d4bc24583eb4ebd73dTruong Nguyen * for selected bundles is added to tsd_array in our thread specific data.
adfc3118ca8c6b541b6a93d4bc24583eb4ebd73dTruong Nguyen *
adfc3118ca8c6b541b6a93d4bc24583eb4ebd73dTruong Nguyen * Assume given file is a manifest unless BUNDLE_PROF flag is set to indicate
adfc3118ca8c6b541b6a93d4bc24583eb4ebd73dTruong Nguyen * it's a profile. For profile bundles, call mhash_test_file() with the
adfc3118ca8c6b541b6a93d4bc24583eb4ebd73dTruong Nguyen * appropriate argument.
9444c26f4faabda140242c3986089704c4073cedTom Whitten *
9444c26f4faabda140242c3986089704c4073cedTom Whitten * The CHECKEXT flag may be set if this was not a directory search request
adfc3118ca8c6b541b6a93d4bc24583eb4ebd73dTruong Nguyen * but a single service bundle file check that was determined by the caller to
9444c26f4faabda140242c3986089704c4073cedTom Whitten * be found based not on the extension of the file.
9444c26f4faabda140242c3986089704c4073cedTom Whitten */
9444c26f4faabda140242c3986089704c4073cedTom Whitten/*ARGSUSED*/
9444c26f4faabda140242c3986089704c4073cedTom Whittenstatic int
9444c26f4faabda140242c3986089704c4073cedTom Whittenprocess(const char *fn, const struct stat *sp, int ftw_type,
9444c26f4faabda140242c3986089704c4073cedTom Whitten struct FTW *ftws)
9444c26f4faabda140242c3986089704c4073cedTom Whitten{
adfc3118ca8c6b541b6a93d4bc24583eb4ebd73dTruong Nguyen int is_profile;
9444c26f4faabda140242c3986089704c4073cedTom Whitten char *suffix_match;
9444c26f4faabda140242c3986089704c4073cedTom Whitten uchar_t hash[MHASH_SIZE];
9444c26f4faabda140242c3986089704c4073cedTom Whitten char *pname;
9444c26f4faabda140242c3986089704c4073cedTom Whitten mftsd_t *tsdp;
9444c26f4faabda140242c3986089704c4073cedTom Whitten
9444c26f4faabda140242c3986089704c4073cedTom Whitten if (ftw_type != FTW_F)
9444c26f4faabda140242c3986089704c4073cedTom Whitten return (0);
9444c26f4faabda140242c3986089704c4073cedTom Whitten
9444c26f4faabda140242c3986089704c4073cedTom Whitten tsdp = get_thread_specific_data();
9444c26f4faabda140242c3986089704c4073cedTom Whitten if (tsdp == NULL)
9444c26f4faabda140242c3986089704c4073cedTom Whitten return (-1);
9444c26f4faabda140242c3986089704c4073cedTom Whitten
9444c26f4faabda140242c3986089704c4073cedTom Whitten /*
9444c26f4faabda140242c3986089704c4073cedTom Whitten * Only check the extension on the file when
9444c26f4faabda140242c3986089704c4073cedTom Whitten * requested.
9444c26f4faabda140242c3986089704c4073cedTom Whitten */
9444c26f4faabda140242c3986089704c4073cedTom Whitten if (tsdp->tsd_flags & CHECKEXT) {
9444c26f4faabda140242c3986089704c4073cedTom Whitten suffix_match = strstr(fn, ".xml");
9444c26f4faabda140242c3986089704c4073cedTom Whitten if (suffix_match == NULL || strcmp(suffix_match, ".xml") != 0)
9444c26f4faabda140242c3986089704c4073cedTom Whitten return (0);
9444c26f4faabda140242c3986089704c4073cedTom Whitten }
9444c26f4faabda140242c3986089704c4073cedTom Whitten
9444c26f4faabda140242c3986089704c4073cedTom Whitten if (tsdp->tsd_flags & CHECKHASH) {
adfc3118ca8c6b541b6a93d4bc24583eb4ebd73dTruong Nguyen is_profile = (tsdp->tsd_flags & BUNDLE_PROF) ? 1 : 0;
adfc3118ca8c6b541b6a93d4bc24583eb4ebd73dTruong Nguyen if (mhash_test_file(tsdp->tsd_hndl, fn, is_profile, &pname,
adfc3118ca8c6b541b6a93d4bc24583eb4ebd73dTruong Nguyen hash) == MHASH_NEWFILE) {
9444c26f4faabda140242c3986089704c4073cedTom Whitten return (add_pointer(tsdp, fn, pname, hash));
9444c26f4faabda140242c3986089704c4073cedTom Whitten }
9444c26f4faabda140242c3986089704c4073cedTom Whitten } else {
9444c26f4faabda140242c3986089704c4073cedTom Whitten return (add_pointer(tsdp, fn, NULL, NULL));
9444c26f4faabda140242c3986089704c4073cedTom Whitten }
9444c26f4faabda140242c3986089704c4073cedTom Whitten
9444c26f4faabda140242c3986089704c4073cedTom Whitten return (0);
9444c26f4faabda140242c3986089704c4073cedTom Whitten}
9444c26f4faabda140242c3986089704c4073cedTom Whitten
9444c26f4faabda140242c3986089704c4073cedTom Whitten/*
9444c26f4faabda140242c3986089704c4073cedTom Whitten * This function returns a pointer to an array of manifest_info_t pointers.
adfc3118ca8c6b541b6a93d4bc24583eb4ebd73dTruong Nguyen * There is one manifest_info_t pointer for each service bundle file in the
9444c26f4faabda140242c3986089704c4073cedTom Whitten * directory, dir, that satifies the selection criteria. The array is
9444c26f4faabda140242c3986089704c4073cedTom Whitten * returned to arrayp. The array will be terminated with a NULL pointer.
9444c26f4faabda140242c3986089704c4073cedTom Whitten * It is the responsibility of the caller to free the memory associated
9444c26f4faabda140242c3986089704c4073cedTom Whitten * with the array by calling free_manifest_array().
9444c26f4faabda140242c3986089704c4073cedTom Whitten *
9444c26f4faabda140242c3986089704c4073cedTom Whitten * flags :
adfc3118ca8c6b541b6a93d4bc24583eb4ebd73dTruong Nguyen * 0x1 - CHECKHASH - do the hash check and only return bundle
9444c26f4faabda140242c3986089704c4073cedTom Whitten * files that do not have a hash entry in the smf/manifest table
adfc3118ca8c6b541b6a93d4bc24583eb4ebd73dTruong Nguyen * or the hash value has changed due to the bundle file having
adfc3118ca8c6b541b6a93d4bc24583eb4ebd73dTruong Nguyen * been modified. If not set then all service bundle files found
adfc3118ca8c6b541b6a93d4bc24583eb4ebd73dTruong Nguyen * are returned, regardless of the hash status.
9444c26f4faabda140242c3986089704c4073cedTom Whitten *
9444c26f4faabda140242c3986089704c4073cedTom Whitten * 0x2 - CHECKEXT - Check the extension of the file is .xml
9444c26f4faabda140242c3986089704c4073cedTom Whitten *
adfc3118ca8c6b541b6a93d4bc24583eb4ebd73dTruong Nguyen * On success a count of the number of selected bundles is returned.
9444c26f4faabda140242c3986089704c4073cedTom Whitten * Note, however, that *arrayp will be set to NULL if the selection is
9444c26f4faabda140242c3986089704c4073cedTom Whitten * empty, and a count of 0 will be returned. In the case of failure, -1
9444c26f4faabda140242c3986089704c4073cedTom Whitten * will be returned and errno will be set.
293e3ab30a546cd932ee22f9d54b3979fcb52095Truong Q. Nguyen *
293e3ab30a546cd932ee22f9d54b3979fcb52095Truong Q. Nguyen * This function takes a repository handle argument from the caller and saves
293e3ab30a546cd932ee22f9d54b3979fcb52095Truong Q. Nguyen * that handle in a thread specific data structure. The thread specific
293e3ab30a546cd932ee22f9d54b3979fcb52095Truong Q. Nguyen * repository handle is used in process() to communicate with the appropriate
293e3ab30a546cd932ee22f9d54b3979fcb52095Truong Q. Nguyen * repository. Thus callers should take care of thread safety with respect to
293e3ab30a546cd932ee22f9d54b3979fcb52095Truong Q. Nguyen * the repository handle. Currently, the two callers of find_manifests are both
293e3ab30a546cd932ee22f9d54b3979fcb52095Truong Q. Nguyen * single threaded, i.e. svccfg and mfstscan, so thread safety not an issue.
9444c26f4faabda140242c3986089704c4073cedTom Whitten */
9444c26f4faabda140242c3986089704c4073cedTom Whittenint
293e3ab30a546cd932ee22f9d54b3979fcb52095Truong Q. Nguyenfind_manifests(scf_handle_t *hndl, const char *dir,
293e3ab30a546cd932ee22f9d54b3979fcb52095Truong Q. Nguyen manifest_info_t ***arrayp, int flags)
9444c26f4faabda140242c3986089704c4073cedTom Whitten{
9444c26f4faabda140242c3986089704c4073cedTom Whitten mftsd_t *tsdp;
9444c26f4faabda140242c3986089704c4073cedTom Whitten int status = -1;
9444c26f4faabda140242c3986089704c4073cedTom Whitten int count;
9444c26f4faabda140242c3986089704c4073cedTom Whitten
9444c26f4faabda140242c3986089704c4073cedTom Whitten tsdp = get_thread_specific_data();
9444c26f4faabda140242c3986089704c4073cedTom Whitten if (tsdp == NULL)
23f76dc290ca84b3df56bf58be0a4b8e3a7e38abRichard Lowe return (-1);
9444c26f4faabda140242c3986089704c4073cedTom Whitten
9444c26f4faabda140242c3986089704c4073cedTom Whitten tsdp->tsd_flags = flags;
9444c26f4faabda140242c3986089704c4073cedTom Whitten
9444c26f4faabda140242c3986089704c4073cedTom Whitten if (tsdp->tsd_flags & CHECKHASH) {
293e3ab30a546cd932ee22f9d54b3979fcb52095Truong Q. Nguyen tsdp->tsd_hndl = hndl;
9444c26f4faabda140242c3986089704c4073cedTom Whitten }
9444c26f4faabda140242c3986089704c4073cedTom Whitten
9444c26f4faabda140242c3986089704c4073cedTom Whitten if (nftw(dir, process, MAX_DEPTH, FTW_MOUNT) == 0) {
9444c26f4faabda140242c3986089704c4073cedTom Whitten status = 0;
9444c26f4faabda140242c3986089704c4073cedTom Whitten }
9444c26f4faabda140242c3986089704c4073cedTom Whitten
9444c26f4faabda140242c3986089704c4073cedTom Whittenout:
9444c26f4faabda140242c3986089704c4073cedTom Whitten if (status == 0) {
9444c26f4faabda140242c3986089704c4073cedTom Whitten *arrayp = tsdp->tsd_array;
9444c26f4faabda140242c3986089704c4073cedTom Whitten count = tsdp->tsd_count;
9444c26f4faabda140242c3986089704c4073cedTom Whitten } else {
9444c26f4faabda140242c3986089704c4073cedTom Whitten *arrayp = NULL;
9444c26f4faabda140242c3986089704c4073cedTom Whitten free_manifest_array(tsdp->tsd_array);
9444c26f4faabda140242c3986089704c4073cedTom Whitten count = -1;
9444c26f4faabda140242c3986089704c4073cedTom Whitten }
9444c26f4faabda140242c3986089704c4073cedTom Whitten
9444c26f4faabda140242c3986089704c4073cedTom Whitten /* Reset thread specific data. */
9444c26f4faabda140242c3986089704c4073cedTom Whitten (void) memset(tsdp, 0, sizeof (*tsdp));
9444c26f4faabda140242c3986089704c4073cedTom Whitten
9444c26f4faabda140242c3986089704c4073cedTom Whitten return (count);
9444c26f4faabda140242c3986089704c4073cedTom Whitten}
9444c26f4faabda140242c3986089704c4073cedTom Whitten
9444c26f4faabda140242c3986089704c4073cedTom Whitten/*
9444c26f4faabda140242c3986089704c4073cedTom Whitten * Free the memory associated with the array of manifest_info structures.
9444c26f4faabda140242c3986089704c4073cedTom Whitten */
9444c26f4faabda140242c3986089704c4073cedTom Whittenvoid
9444c26f4faabda140242c3986089704c4073cedTom Whittenfree_manifest_array(manifest_info_t **array)
9444c26f4faabda140242c3986089704c4073cedTom Whitten{
9444c26f4faabda140242c3986089704c4073cedTom Whitten manifest_info_t **entry;
9444c26f4faabda140242c3986089704c4073cedTom Whitten manifest_info_t *info;
9444c26f4faabda140242c3986089704c4073cedTom Whitten
9444c26f4faabda140242c3986089704c4073cedTom Whitten if (array == NULL)
9444c26f4faabda140242c3986089704c4073cedTom Whitten return;
9444c26f4faabda140242c3986089704c4073cedTom Whitten
9444c26f4faabda140242c3986089704c4073cedTom Whitten for (entry = array; *entry != NULL; entry++) {
9444c26f4faabda140242c3986089704c4073cedTom Whitten info = *entry;
9444c26f4faabda140242c3986089704c4073cedTom Whitten uu_free((void *) info->mi_path);
9444c26f4faabda140242c3986089704c4073cedTom Whitten uu_free((void *) info->mi_prop);
9444c26f4faabda140242c3986089704c4073cedTom Whitten uu_free(info);
9444c26f4faabda140242c3986089704c4073cedTom Whitten }
9444c26f4faabda140242c3986089704c4073cedTom Whitten
9444c26f4faabda140242c3986089704c4073cedTom Whitten /*
9444c26f4faabda140242c3986089704c4073cedTom Whitten * Array is allocated with realloc(3C), so it must be freed with
9444c26f4faabda140242c3986089704c4073cedTom Whitten * free(3c) rather than uu_free().
9444c26f4faabda140242c3986089704c4073cedTom Whitten */
9444c26f4faabda140242c3986089704c4073cedTom Whitten free(array);
9444c26f4faabda140242c3986089704c4073cedTom Whitten}