65451a03349bdb7f4bf79a8f29d4065772e01caeReza Sabdar * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * BSD 3 Clause License
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Copyright (c) 2007, The Storage Networking Industry Association.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Redistribution and use in source and binary forms, with or without
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * modification, are permitted provided that the following conditions
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * - Redistributions of source code must retain the above copyright
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * notice, this list of conditions and the following disclaimer.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * - Redistributions in binary form must reproduce the above copyright
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * notice, this list of conditions and the following disclaimer in
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * the documentation and/or other materials provided with the
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * distribution.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * - Neither the name of The Storage Networking Industry Association (SNIA)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * nor the names of its contributors may be used to endorse or promote
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * products derived from this software without specific prior written
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * permission.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * POSSIBILITY OF SUCH DAMAGE.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * This file implemets the post-order, pre-order and level-order
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * traversing of the file system. The related macros and constants
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * are defined in traverse.h.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Check if it's "." or ".."
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if ((name[1] == 0) || (name[1] == '.' && name[2] == 0))
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Macros on fs_traverse flags.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#define STOP_ONERR(f) ((f)->ft_flags & FST_STOP_ONERR)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#define STOP_ONLONG(f) ((f)->ft_flags & FST_STOP_ONLONG)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * The traversing state that is pushed onto the stack.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * This include:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * - The end of the path of the current directory.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * - The position of the last component on it.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * - The read position in the directory.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * - The file handle of the directory.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * - The stat of the directory.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar long ts_dpos; /* position in the directory when reading its entries */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Statistics gathering structure.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Global instance of statistics variable.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdartypedef struct {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic int traverse_level_nondir(struct fs_traverse *ftp,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Gather some directory entry information and return them
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /* LINTED improper alignment */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar dent = (fs_dent_info_t *)(darg->da_buf + darg->da_end);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Creates a new traversing state based on the path passed to it.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Create a file handle and get stats for the given path
84bf06e9e5fd6d61897cc8c298a0f3e807b27094Reza Sabdarfs_getstat(char *path, fs_fhandle_t *fh, struct stat64 *st)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Get directory entries info and return in the buffer. Cookie
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * will keep the state of each call
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarfs_getdents(int fildes, struct dirent *buf, size_t *nbyte,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (*nbyte == 0) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) memset((char *)buf, 0, MAX_DENT_BUF_SIZE);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *nbyte = rv = getdents(fildes, buf, darg->da_size);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /* LINTED improper alignment */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) snprintf(file_path, PATH_MAX, "%s/", pn_path);
65451a03349bdb7f4bf79a8f29d4065772e01caeReza Sabdar (void) strlcat(file_path, ptr->d_name, PATH_MAX + 1);
5a3c8170a75e81911cf43e0eb9ad5cdabb5f1e39Reza Sabdar if (fs_populate_dents(darg, strlen(ptr->d_name),
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Read the directory entries and return the information about
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * each entry
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarfs_readdir(fs_fhandle_t *ts_fh, char *path, long *dpos,
84bf06e9e5fd6d61897cc8c298a0f3e807b27094Reza Sabdar char *nm, int *el, fs_fhandle_t *efh, struct stat64 *est)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) snprintf(file_path, PATH_MAX, "%s/", path);
65451a03349bdb7f4bf79a8f29d4065772e01caeReza Sabdar (void) strlcat(file_path, dp->d_name, PATH_MAX + 1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Traverse the file system in the post-order way. The description
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * and example is in the header file.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * The callback function should return 0, on success and non-zero on
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * failure. If the callback function returns non-zero return value,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * the traversing stops.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar char path[PATH_MAX + 1]; /* full path name of the current dir */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar char nm[NAME_MAX + 1]; /* directory entry name */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int pl, el; /* path and directory entry length */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar struct fst_node pn, en; /* parent and entry nodes */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (!ftp || !ftp->ft_path || !*ftp->ft_path || !ftp->ft_callbk) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /* set the default log function if it's not already set */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "Log to system log \"%s\"", ftp->ft_path);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /* set the logical path to physical path if it's not already set */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "lpath too long \"%s\"", ftp->ft_path);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "Error %d on fs_getstat(%s)", rv, ftp->ft_path);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "CALLBACK(%s): %d", pn.tn_path, rv);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "Error %d on readdir(%s) pos %d",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /* done with this directory */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Push the current directory on to the stack and
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * dive into the entry found.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Concatenate the current entry with the
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * current path. This will be the path of
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * the new directory to be scanned.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * sprintf(tsp->ts_end, "/%s", de->d_name);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * could be used here, but concatenating
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * strings like this might be faster.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * The length of the new path has been
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * checked above. So strcpy() can be
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * safe and should not lead to a buffer
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * The entry is not a directory so the
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * callback function must be called.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "CALLBACK(%s/%s): %d",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar } while (rv == 0);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * A new directory must be processed, go to the start of
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * the loop, open it and process it.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar rv = 0; /* We should skip the current directory */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Remove the ent from the end of path and send it
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * as an entry of the path.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Does not need to free tsp here. It will be released
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar } while (rv == 0);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * For the 'ftp->ft_path' directory itself.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "CALLBACK(%s): %d", pn.tn_path, rv);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Pop and free all the remaining entries on the stack.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar while (!cstack_pop(sp, (void **)&tsp, (int *)NULL)) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * In one pass, read all the directory entries of the specified
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * directory and call the callback function for non-directory
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * On return:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * 0: Lets the directory to be scanned for directory entries.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * < 0: Completely stops traversing.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * FST_SKIP: stops further scanning of the directory. Traversing
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * will continue with the next directory in the hierarchy.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * SKIP_ENTRY: Failed to get the directory entries, so the caller
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * should skip this entry.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar traverse_state_t *tsp, struct fst_node *pnp, dent_arg_t *darg)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar while (rv == 0) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar rv = fs_getdents(fd, buf, &len, pnp->tn_path, &tsp->ts_dpos,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "Error %d on readdir(%s) pos %d",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * We cannot read the directory entry, we should
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * skip to the next directory.
5a3c8170a75e81911cf43e0eb9ad5cdabb5f1e39Reza Sabdar /* Break at the end of directory */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /* LINTED imporper alignment */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /* LINTED imporper alignment */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar for (i = 0; i < n_entries; i++, dent = (fs_dent_info_t *)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * The entry is not a directory so the callback
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * function must be called.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Traverse the file system in the level-order way. The description
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * and example is in the header file.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar char path[PATH_MAX + 1]; /* full path name of the current dir */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar char nm[NAME_MAX + 1]; /* directory entry name */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int pl, el; /* path and directory entry length */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar struct fst_node pn, en; /* parent and entry nodes */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (!ftp || !ftp->ft_path || !*ftp->ft_path || !ftp->ft_callbk) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /* set the default log function if it's not already set */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "Log to system log \"%s\"", ftp->ft_path);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "lpath too long \"%s\"", ftp->ft_path);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "Error %d on fs_getstat(%s)", rv, ftp->ft_path);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "CALLBACK(%s): %d", pn.tn_path, rv);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /* call the callback function on the path itself */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar rv = traverse_level_nondir(ftp, tsp, &pn, &darg);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * If skipped by the callback function or
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * error happened reading the information
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * N.B. next_dir should be set to 0 as
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * well. This prevents the infinite loop.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * If it's not set the same directory will
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * be poped from the stack and will be
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * scanned again.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /* re-start reading entries of the directory */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "Error %d on readdir(%s) pos %d",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /* done with this directory */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * The long paths were already encountered
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * when processing non-dir entries in.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * traverse_level_nondir.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * We don't increase fss_longpath_err
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * counter for them again here.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Call the callback function for the new
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * directory found, then push the current
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * directory on to the stack. Then dive
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * into the entry found.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Push the current directory on to the stack and
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * dive into the entry found.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar } while (rv == 0);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * A new directory must be processed, go to the start of
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * the loop, open it and process it.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar } while (rv == 0);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Pop and free all the remaining entries on the stack.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar while (!cstack_pop(sp, (void **)&tsp, (int *)NULL)) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * filecopy - Copy a file
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Parameters:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * char *dest - Destination path
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * char *src - Source path
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * 0 - No errors
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * #0 - Error occured
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * -4 - read/write error
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * -5 - source modified during copy
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Simplified version for Solaris
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-2);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-3);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-2);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /* short read/write, remove the partial file */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-4);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-2);