manifest_find.c revision adfc3118ca8c6b541b6a93d4bc24583eb4ebd73d
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
*/
/*
* The primary role of this file is to obtain a list of manifests that are
* located in a specified directory or one of its subdirectories. The
* find_manifests() function provides this service, and
* free_manifest_array() is used to free the memory associated with the
* returned list.
*
* The find_manifests() function can return an array consisting of all the
* .xml files in the directory and its subdirectories. Alternatively,
* find_manifests() can be asked to only return new manifests based on the
* return of mhash_test_file(). The list that is returned is an array of
* pointers to manifest_info structures.
*
* Implementation Notes:
* ====================
* This module makes use of the nftw(3C) function to scan the directory.
* nftw() calls a processing function for every file that it finds.
* Unfortunately, nftw does not allow us to pass in any structure pointers
* to the processing function, and that makes it hard to accumulate a list.
* Thus, we will use the thread specific data area to hold data that must
* be retained between calls to the processing function. This will allow
* this module to be used in multi-threaded applications if the need
* arises.
*/
#include <assert.h>
#include <errno.h>
#include <ftw.h>
#include <libscf.h>
#include <libuutil.h>
#include <pthread.h>
#include <stdlib.h>
#include <string.h>
#include "manifest_find.h"
#include "manifest_hash.h"
#define MAX_DEPTH 24
/* Thread specific data */
typedef struct mftsd {
int tsd_count; /* Number items in list */
int tsd_max; /* Number of pointers allocated */
/* at tsd_array. */
int tsd_flags; /* Check flags for hash and extension */
} mftsd_t;
/*
* Add the manifest info consisting of filename (fn), hash property name
* (pname) and hash to the array at tsd_array. If necessary, realloc()
* will be called to increase the size of the buffer at tsd_array.
*
* Returns 0 on success and -1 on failure. If a failure occurs, errno will
* be set.
*/
static int
{
int new_max;
/* Need more memory. */
return (-1);
/* NULL terminate list in case allocations fail below. */
}
return (-1);
}
return (-1);
}
/* NULL terminate the list. */
return (0);
}
/*
* If necessary initialize the thread specific data key at tsd_key, and
* allocate a mftsd_t structure to hold our thread specific data. Upon
* success, the address the thread specific data is returned. On failure,
* NULL is returned and errno is set.
*/
static mftsd_t *
{
return (NULL);
/*
* First time for this thread. We need to allocate memory
* for our thread specific data.
*/
return (NULL);
}
if (errno != 0) {
/*
* EINVAL means that our key is invalid, which
* would be a coding error.
*/
return (NULL);
}
}
return (tsdp);
}
/*
* This function is called by nftw(3C) every time that it finds an object
* in a directory of interest. If the object is a file, process() checks
* to see if it is a service bundle file by insuring that it has a .xml
* extension.
*
* If the file is a service bundle file, and the CHECKHASH flag is set process()
* calls mhash_test_file() to see if it is a new bundle. Bundle file data
* for selected bundles is added to tsd_array in our thread specific data.
*
* Assume given file is a manifest unless BUNDLE_PROF flag is set to indicate
* it's a profile. For profile bundles, call mhash_test_file() with the
* appropriate argument.
*
* The CHECKEXT flag may be set if this was not a directory search request
* but a single service bundle file check that was determined by the caller to
* be found based not on the extension of the file.
*/
/*ARGSUSED*/
static int
{
int is_profile;
char *suffix_match;
char *pname;
return (0);
return (-1);
/*
* Only check the extension on the file when
* requested.
*/
return (0);
}
hash) == MHASH_NEWFILE) {
}
} else {
}
return (0);
}
/*
* This function returns a pointer to an array of manifest_info_t pointers.
* There is one manifest_info_t pointer for each service bundle file in the
* directory, dir, that satifies the selection criteria. The array is
* returned to arrayp. The array will be terminated with a NULL pointer.
* It is the responsibility of the caller to free the memory associated
* with the array by calling free_manifest_array().
*
* flags :
* 0x1 - CHECKHASH - do the hash check and only return bundle
* or the hash value has changed due to the bundle file having
* been modified. If not set then all service bundle files found
* are returned, regardless of the hash status.
*
* 0x2 - CHECKEXT - Check the extension of the file is .xml
*
* On success a count of the number of selected bundles is returned.
* Note, however, that *arrayp will be set to NULL if the selection is
* empty, and a count of 0 will be returned. In the case of failure, -1
* will be returned and errno will be set.
*/
int
{
int status = -1;
int count;
return (NULL);
/*
* Create a handle for use by mhast_test_file() if
* the flag is set to request hash checking be enabled.
*/
if (scf_error() == SCF_ERROR_NO_MEMORY) {
} else {
}
goto out;
}
if (scf_error() == SCF_ERROR_NO_RESOURCES) {
} else {
}
goto out;
}
}
status = 0;
}
out:
}
if (status == 0) {
} else {
count = -1;
}
/* Reset thread specific data. */
return (count);
}
/*
* Free the memory associated with the array of manifest_info structures.
*/
void
{
return;
}
/*
* Array is allocated with realloc(3C), so it must be freed with
* free(3c) rather than uu_free().
*/
}