xref: /titanic_44/usr/src/cmd/fs.d/cachefs/cachefspack/docmds.c (revision 47644099886aa8d3f43120b9eede3044342be473)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
57c478bd9Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
67c478bd9Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
77c478bd9Sstevel@tonic-gate  * with the License.
87c478bd9Sstevel@tonic-gate  *
97c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
107c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
117c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
127c478bd9Sstevel@tonic-gate  * and limitations under the License.
137c478bd9Sstevel@tonic-gate  *
147c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
157c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
167c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
177c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
187c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
197c478bd9Sstevel@tonic-gate  *
207c478bd9Sstevel@tonic-gate  * CDDL HEADER END
217c478bd9Sstevel@tonic-gate  */
227c478bd9Sstevel@tonic-gate /*
23*47644099Sgt29601  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
247c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
257c478bd9Sstevel@tonic-gate  */
267c478bd9Sstevel@tonic-gate 
277c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
287c478bd9Sstevel@tonic-gate 
297c478bd9Sstevel@tonic-gate #include <locale.h>
307c478bd9Sstevel@tonic-gate #include <sys/types.h>
317c478bd9Sstevel@tonic-gate #include <sys/param.h>
327c478bd9Sstevel@tonic-gate #include <stdio.h>
337c478bd9Sstevel@tonic-gate #include <string.h>
347c478bd9Sstevel@tonic-gate #include <errno.h>
357c478bd9Sstevel@tonic-gate #include <search.h>
367c478bd9Sstevel@tonic-gate 
377c478bd9Sstevel@tonic-gate #include <dirent.h>
387c478bd9Sstevel@tonic-gate #include <fnmatch.h>
397c478bd9Sstevel@tonic-gate #include <sys/stat.h>
407c478bd9Sstevel@tonic-gate 
417c478bd9Sstevel@tonic-gate #include "rules.h"
427c478bd9Sstevel@tonic-gate 
437c478bd9Sstevel@tonic-gate extern char *mstrdup(const char *);
447c478bd9Sstevel@tonic-gate 
457c478bd9Sstevel@tonic-gate /*
467c478bd9Sstevel@tonic-gate  * The do_base_dir() function is called when a BASE command is encountered
477c478bd9Sstevel@tonic-gate  * in the input directives or end-of-file is reach on the input directive
487c478bd9Sstevel@tonic-gate  * file. This function causes the commands associated with the previous
497c478bd9Sstevel@tonic-gate  * BASE command to be executed. for example,
507c478bd9Sstevel@tonic-gate  *
517c478bd9Sstevel@tonic-gate  *	BASE a/b/c
527c478bd9Sstevel@tonic-gate  *	LIST ...
537c478bd9Sstevel@tonic-gate  *	IGNORE ...
547c478bd9Sstevel@tonic-gate  *	BASE d/e/f (this command will cause do_base_dir() to be called for
557c478bd9Sstevel@tonic-gate  *		   base directory a/b/c)
567c478bd9Sstevel@tonic-gate  *
577c478bd9Sstevel@tonic-gate  * Input arguments:
587c478bd9Sstevel@tonic-gate  *	dirpath - the BASE directory being operated on
597c478bd9Sstevel@tonic-gate  *	incld_lst - A list of strings to be matched obtained from the
607c478bd9Sstevel@tonic-gate  *		    LIST commands associated with the BASE directory.
617c478bd9Sstevel@tonic-gate  *	excld_lst - A list of strings to be matched obtained from the
627c478bd9Sstevel@tonic-gate  *		    IGNORE commands associated with the BASE directory.
637c478bd9Sstevel@tonic-gate  *	func	- A function to be called for each matched file. The
647c478bd9Sstevel@tonic-gate  *		  functions allow files to be  packed, unpacked,
657c478bd9Sstevel@tonic-gate  *		  examined and filenames printed.
667c478bd9Sstevel@tonic-gate  */
677c478bd9Sstevel@tonic-gate 
687c478bd9Sstevel@tonic-gate void
do_base_dir(char * dirpath,struct item * incld_lst,struct item * excld_lst,int (* func)(char *,char *,DIR *,int))697c478bd9Sstevel@tonic-gate do_base_dir(char *dirpath, struct item *incld_lst, struct item *excld_lst,
707c478bd9Sstevel@tonic-gate     int (*func)(char *, char *, DIR *, int))
717c478bd9Sstevel@tonic-gate {
727c478bd9Sstevel@tonic-gate 	struct item *iitem;
737c478bd9Sstevel@tonic-gate 	int err;
747c478bd9Sstevel@tonic-gate 	int files_processed = 0;
757c478bd9Sstevel@tonic-gate 	struct item symlk_hd, *symlk, *symlk_sv;
767c478bd9Sstevel@tonic-gate 	struct stat64 statbuf;
777c478bd9Sstevel@tonic-gate 	char linkbuf[MAXPATHLEN];
787c478bd9Sstevel@tonic-gate 	int sz;
797c478bd9Sstevel@tonic-gate 	char *s;
807c478bd9Sstevel@tonic-gate 	char *mk_base_dir(char *, char *);
817c478bd9Sstevel@tonic-gate 
827c478bd9Sstevel@tonic-gate #ifdef DEBUG
837c478bd9Sstevel@tonic-gate 	prtitem("Global IGNOREs", &gign_hd);
847c478bd9Sstevel@tonic-gate 	prtitem("LIST cmds", &list_hd);
857c478bd9Sstevel@tonic-gate 	prtitem("Local IGNOREs", &lign_hd);
867c478bd9Sstevel@tonic-gate #endif /* DEBUG */
877c478bd9Sstevel@tonic-gate 
887c478bd9Sstevel@tonic-gate 
897c478bd9Sstevel@tonic-gate 	symlk = &symlk_hd;
907c478bd9Sstevel@tonic-gate 	symlk_hd.i_next = (struct item *)0;
917c478bd9Sstevel@tonic-gate 
927c478bd9Sstevel@tonic-gate 	iitem  = incld_lst->i_next;
937c478bd9Sstevel@tonic-gate 	if (iitem == (struct item *)0)
947c478bd9Sstevel@tonic-gate 		return;
957c478bd9Sstevel@tonic-gate 	while (iitem != (struct item *)0) {
967c478bd9Sstevel@tonic-gate #ifdef DEBUG
977c478bd9Sstevel@tonic-gate 		printf("do_base_dir: iitem->i_str = %s  iitem->i_flag = %x\n",
987c478bd9Sstevel@tonic-gate 		    iitem->i_str, iitem->i_flag);
997c478bd9Sstevel@tonic-gate 		fflush(stdout);
1007c478bd9Sstevel@tonic-gate #endif /* DEBUG */
1017c478bd9Sstevel@tonic-gate 		err = do_list_item(dirpath, iitem->i_str,
1027c478bd9Sstevel@tonic-gate 		    iitem->i_flag, excld_lst, 0, &symlk, func);
1037c478bd9Sstevel@tonic-gate 		if (err == 0) {
1047c478bd9Sstevel@tonic-gate 			fprintf(stderr,
1057c478bd9Sstevel@tonic-gate 			    gettext("cachefspack: basedir = %s"),
1067c478bd9Sstevel@tonic-gate 			    dirpath);
1077c478bd9Sstevel@tonic-gate 			fprintf(stderr,
1087c478bd9Sstevel@tonic-gate 			    gettext("    %s - no file(s) selected\n"),
1097c478bd9Sstevel@tonic-gate 			    iitem->i_str);
1107c478bd9Sstevel@tonic-gate 		}
1117c478bd9Sstevel@tonic-gate 		iitem = iitem->i_next;
1127c478bd9Sstevel@tonic-gate 	};
1137c478bd9Sstevel@tonic-gate 	/*
1147c478bd9Sstevel@tonic-gate 	 * Invoke 'func' for each component of the BASE
1157c478bd9Sstevel@tonic-gate 	 * directory.
1167c478bd9Sstevel@tonic-gate 	 */
1177c478bd9Sstevel@tonic-gate 	func_dir_path(dirpath, func);
1187c478bd9Sstevel@tonic-gate 
1197c478bd9Sstevel@tonic-gate 	if (lstat64(dirpath, &statbuf) < 0) {
1207c478bd9Sstevel@tonic-gate 		perror(gettext("Can't stat base directory"));
1217c478bd9Sstevel@tonic-gate 	} else {
1227c478bd9Sstevel@tonic-gate 		if (S_ISLNK(statbuf.st_mode)) {
1237c478bd9Sstevel@tonic-gate 			sz = readlink(dirpath, linkbuf, MAXPATHLEN-1);
1247c478bd9Sstevel@tonic-gate 			if (sz > 0) {
1257c478bd9Sstevel@tonic-gate 				linkbuf[sz] = '\0';
1267c478bd9Sstevel@tonic-gate 				s = mk_base_dir(dirpath, linkbuf);
1277c478bd9Sstevel@tonic-gate 				if (s != (char *)0) {
1287c478bd9Sstevel@tonic-gate 					func_dir_path(s, func);
1297c478bd9Sstevel@tonic-gate 				}
1307c478bd9Sstevel@tonic-gate 			}
1317c478bd9Sstevel@tonic-gate 		}
1327c478bd9Sstevel@tonic-gate 	}
1337c478bd9Sstevel@tonic-gate 
1347c478bd9Sstevel@tonic-gate #ifdef DEBUG
1357c478bd9Sstevel@tonic-gate 	prtitem("Symbolic Links", &symlk_hd);
1367c478bd9Sstevel@tonic-gate #endif /* DEBUG */
1377c478bd9Sstevel@tonic-gate 	iitem = symlk_hd.i_next;
1387c478bd9Sstevel@tonic-gate 	if (iitem == (struct item *)0)
1397c478bd9Sstevel@tonic-gate 		return;
1407c478bd9Sstevel@tonic-gate 	while (iitem != (struct item *)0) {
1417c478bd9Sstevel@tonic-gate #ifdef DEBUG
1427c478bd9Sstevel@tonic-gate 		printf("do_bas sl: iitem->i_str = %s  iitem->i_flag = %x\n",
1437c478bd9Sstevel@tonic-gate 		    iitem->i_str, iitem->i_flag);
1447c478bd9Sstevel@tonic-gate 		fflush(stdout);
1457c478bd9Sstevel@tonic-gate #endif /* DEBUG */
1467c478bd9Sstevel@tonic-gate 		files_processed = do_list_item(iitem->i_str, "*",
1477c478bd9Sstevel@tonic-gate 		    (LF_SYMLINK | LF_REGEX), excld_lst, 0, &symlk, func);
1487c478bd9Sstevel@tonic-gate 		if (files_processed) {
1497c478bd9Sstevel@tonic-gate 			/*
1507c478bd9Sstevel@tonic-gate 			 * Invoke 'func' for each component of the BASE
1517c478bd9Sstevel@tonic-gate 			 * directory.
1527c478bd9Sstevel@tonic-gate 			 */
1537c478bd9Sstevel@tonic-gate 			func_dir_path(iitem->i_str, func);
1547c478bd9Sstevel@tonic-gate 		}
1557c478bd9Sstevel@tonic-gate 		symlk_sv = iitem;
1567c478bd9Sstevel@tonic-gate 		iitem = iitem->i_next;
1577c478bd9Sstevel@tonic-gate 		symlk_hd.i_next = iitem;
1587c478bd9Sstevel@tonic-gate 		free(symlk_sv);
1597c478bd9Sstevel@tonic-gate #ifdef DEBUG
1607c478bd9Sstevel@tonic-gate 		prtitem("Symbolic Links loop", &symlk_hd);
1617c478bd9Sstevel@tonic-gate #endif /* DEBUG */
1627c478bd9Sstevel@tonic-gate 	}
1637c478bd9Sstevel@tonic-gate }
1647c478bd9Sstevel@tonic-gate 
1657c478bd9Sstevel@tonic-gate /*
1667c478bd9Sstevel@tonic-gate  * The do_list_item() function is called for each LIST item associated with
1677c478bd9Sstevel@tonic-gate  * a BASE directory. It does the work of descending directories and matching
1687c478bd9Sstevel@tonic-gate  * filenames.
1697c478bd9Sstevel@tonic-gate  *
1707c478bd9Sstevel@tonic-gate  * Input arguments:
1717c478bd9Sstevel@tonic-gate  *	dirpath - the BASE directory being operated on
1727c478bd9Sstevel@tonic-gate  *	pat - The argument from the LIST command to match
1737c478bd9Sstevel@tonic-gate  *	flags - Flags which affect how patterns are matched:
1747c478bd9Sstevel@tonic-gate  *		LF_STRIP_DOTSLASH - means strip off "." and/or "/" at the
1757c478bd9Sstevel@tonic-gate  *				    beginning of the pattern to match.
1767c478bd9Sstevel@tonic-gate  *		LF_REGEX - Means match the pattern as a regular expression.
1777c478bd9Sstevel@tonic-gate  *			   Otherwise, an exact match of characters is required.
1787c478bd9Sstevel@tonic-gate  *	excld_lst - A list of strings to be matched obtained from the
1797c478bd9Sstevel@tonic-gate  *		    IGNORE commands associated with the BASE directory.
1807c478bd9Sstevel@tonic-gate  *	func - A function to be called for each matched file. The
1817c478bd9Sstevel@tonic-gate  *		functions allow files to be  packed, unpacked,
1827c478bd9Sstevel@tonic-gate  *		examined and filenames printed.
1837c478bd9Sstevel@tonic-gate  *
1847c478bd9Sstevel@tonic-gate  * Return values:
1857c478bd9Sstevel@tonic-gate  *	0 -  'func' NOT invoked for any file
1867c478bd9Sstevel@tonic-gate  *	1 -  'func' invoked for at least 1 file
1877c478bd9Sstevel@tonic-gate  */
1887c478bd9Sstevel@tonic-gate int
do_list_item(char * dirpath,char * pat,int flags,struct item * excld_lst,DIR * pdir,struct item ** symlk_lst,int (* func)(char *,char *,DIR *,int))1897c478bd9Sstevel@tonic-gate do_list_item(char *dirpath, char *pat, int flags, struct item *excld_lst,
1907c478bd9Sstevel@tonic-gate     DIR *pdir, struct item **symlk_lst, int (*func)(char *, char *, DIR *, int))
1917c478bd9Sstevel@tonic-gate {
1927c478bd9Sstevel@tonic-gate 	static char statnam[MAXPATHLEN];
1937c478bd9Sstevel@tonic-gate 	static int glastpos = 0;
1947c478bd9Sstevel@tonic-gate 	static int basedir_lastpos;
1957c478bd9Sstevel@tonic-gate 	static int depth = 0;
1967c478bd9Sstevel@tonic-gate 	static int unwind = 0;
1977c478bd9Sstevel@tonic-gate 	static int do_dir = 0;
1987c478bd9Sstevel@tonic-gate 	static int sl_cnt;
1997c478bd9Sstevel@tonic-gate 	static int retval;
2007c478bd9Sstevel@tonic-gate 	static char linkbuf[MAXPATHLEN];
2017c478bd9Sstevel@tonic-gate 	DIR *dir, *parent_dir;
2027c478bd9Sstevel@tonic-gate 	struct dirent64 *dirent;
2037c478bd9Sstevel@tonic-gate 	int match;
2047c478bd9Sstevel@tonic-gate 	int err;
2057c478bd9Sstevel@tonic-gate 	struct stat64 statbuf;
2067c478bd9Sstevel@tonic-gate 	int llastpos;
2077c478bd9Sstevel@tonic-gate 	struct item *eitem;
2087c478bd9Sstevel@tonic-gate 	int excld_flag;
2097c478bd9Sstevel@tonic-gate 	char *p;
2107c478bd9Sstevel@tonic-gate 	int diropn;
2117c478bd9Sstevel@tonic-gate 	int len;
2127c478bd9Sstevel@tonic-gate 	int sz;
2137c478bd9Sstevel@tonic-gate 	void process_symlk();
2147c478bd9Sstevel@tonic-gate 
2157c478bd9Sstevel@tonic-gate 	strcpy(&statnam[glastpos], dirpath);
2167c478bd9Sstevel@tonic-gate 	len = strlen(statnam) - 1;
2177c478bd9Sstevel@tonic-gate 	if (statnam[len] != '/') {
2187c478bd9Sstevel@tonic-gate 		strcat(statnam, "/");
2197c478bd9Sstevel@tonic-gate 	}
2207c478bd9Sstevel@tonic-gate 	parent_dir = pdir;
2217c478bd9Sstevel@tonic-gate 	llastpos = glastpos;
2227c478bd9Sstevel@tonic-gate 	glastpos = strlen(statnam);
2237c478bd9Sstevel@tonic-gate 	if (depth == 0) {
2247c478bd9Sstevel@tonic-gate 		basedir_lastpos = glastpos;
2257c478bd9Sstevel@tonic-gate 		sl_cnt = slash_cnt(pat);
2267c478bd9Sstevel@tonic-gate 		retval = 0;
2277c478bd9Sstevel@tonic-gate 	}
2287c478bd9Sstevel@tonic-gate 	depth++;
2297c478bd9Sstevel@tonic-gate 
2307c478bd9Sstevel@tonic-gate 	diropn = 0;
2317c478bd9Sstevel@tonic-gate 	dir = opendir(statnam);
2327c478bd9Sstevel@tonic-gate 	if (dir == NULL) {
2337c478bd9Sstevel@tonic-gate 		fprintf(stderr, gettext("\ncachefspack: %s - "), statnam);
2347c478bd9Sstevel@tonic-gate 		perror(gettext("Can't open directory"));
2357c478bd9Sstevel@tonic-gate 		goto out;
2367c478bd9Sstevel@tonic-gate 	}
2377c478bd9Sstevel@tonic-gate 	diropn = 1;
2387c478bd9Sstevel@tonic-gate 
2397c478bd9Sstevel@tonic-gate 	while (1) {
2407c478bd9Sstevel@tonic-gate 		dirent = readdir64(dir);
2417c478bd9Sstevel@tonic-gate 		if (dirent == NULL) { /* EOF */
2427c478bd9Sstevel@tonic-gate 			if ((depth-1) > do_dir) {
2437c478bd9Sstevel@tonic-gate 				do_dir = depth - 1;
2447c478bd9Sstevel@tonic-gate 			}
2457c478bd9Sstevel@tonic-gate 			break;
2467c478bd9Sstevel@tonic-gate 		}
2477c478bd9Sstevel@tonic-gate 		/*
2487c478bd9Sstevel@tonic-gate 		 * If file is '..' skip it
2497c478bd9Sstevel@tonic-gate 		 */
2507c478bd9Sstevel@tonic-gate 		if (strcmp(dirent->d_name, "..") == 0) {
2517c478bd9Sstevel@tonic-gate 			continue;
2527c478bd9Sstevel@tonic-gate 		}
2537c478bd9Sstevel@tonic-gate 		/*
2547c478bd9Sstevel@tonic-gate 		 * Apply excludes if this is not a LISTed directory
2557c478bd9Sstevel@tonic-gate 		 * NOTE: names from IGNORE commands are matched against the
2567c478bd9Sstevel@tonic-gate 		 *	 component name(a name between '/' marks), not the
2577c478bd9Sstevel@tonic-gate 		 *	 whole pathname.
2587c478bd9Sstevel@tonic-gate 		 */
2597c478bd9Sstevel@tonic-gate 		if (flags & LF_SYMLINK) {
2607c478bd9Sstevel@tonic-gate 			match = ((depth-1) >= sl_cnt);
2617c478bd9Sstevel@tonic-gate 		} else {
2627c478bd9Sstevel@tonic-gate 			match = ((depth-1) > sl_cnt);
2637c478bd9Sstevel@tonic-gate 		}
2647c478bd9Sstevel@tonic-gate 		if (match) {
2657c478bd9Sstevel@tonic-gate 			eitem = excld_lst->i_next;
2667c478bd9Sstevel@tonic-gate 			excld_flag = 0;
2677c478bd9Sstevel@tonic-gate 			while (eitem != (struct item *)0) {
2687c478bd9Sstevel@tonic-gate 				match = gmatch(dirent->d_name, eitem->i_str);
2697c478bd9Sstevel@tonic-gate 				if (match == 1) {
2707c478bd9Sstevel@tonic-gate 					excld_flag = 1;
2717c478bd9Sstevel@tonic-gate 					break;
2727c478bd9Sstevel@tonic-gate 				}
2737c478bd9Sstevel@tonic-gate 				eitem = eitem->i_next;
2747c478bd9Sstevel@tonic-gate 			}
2757c478bd9Sstevel@tonic-gate 			if (excld_flag == 1) {
2767c478bd9Sstevel@tonic-gate 				continue;
2777c478bd9Sstevel@tonic-gate 			}
2787c478bd9Sstevel@tonic-gate 		}
2797c478bd9Sstevel@tonic-gate 		strcpy(&statnam[glastpos], dirent->d_name);
2807c478bd9Sstevel@tonic-gate 		err = lstat64(statnam, &statbuf);
2817c478bd9Sstevel@tonic-gate 		if (err < 0) {
2827c478bd9Sstevel@tonic-gate 			fprintf(stderr,
2837c478bd9Sstevel@tonic-gate 			    gettext("cachefspack: %s - stat failed"),
2847c478bd9Sstevel@tonic-gate 			    statnam);
2857c478bd9Sstevel@tonic-gate 			perror(gettext(" "));
2867c478bd9Sstevel@tonic-gate 			continue;
2877c478bd9Sstevel@tonic-gate 		}
2887c478bd9Sstevel@tonic-gate 		p = pat;
2897c478bd9Sstevel@tonic-gate 		if (flags & LF_STRIP_DOTSLASH) {
2907c478bd9Sstevel@tonic-gate 			if (strncmp(p, "./", 2) == 0) {
2917c478bd9Sstevel@tonic-gate 				p += 2;
2927c478bd9Sstevel@tonic-gate 			}
2937c478bd9Sstevel@tonic-gate 		}
2947c478bd9Sstevel@tonic-gate 		if (S_ISDIR(statbuf.st_mode)) {
2957c478bd9Sstevel@tonic-gate #ifdef DEBUG
2967c478bd9Sstevel@tonic-gate 			printf("directory:  &statnam[basedir_lastpos] = %s\n",
2977c478bd9Sstevel@tonic-gate 			&statnam[basedir_lastpos]);
2987c478bd9Sstevel@tonic-gate 			printf("statbuf.st_mode = %o\n", statbuf.st_mode);
2997c478bd9Sstevel@tonic-gate 			printf("depth = %d sl_cnt = %d\n", depth, sl_cnt);
3007c478bd9Sstevel@tonic-gate 			fflush(stdout);
3017c478bd9Sstevel@tonic-gate #endif /* DEBUG */
3027c478bd9Sstevel@tonic-gate 			if ((depth-1) == sl_cnt) {
3037c478bd9Sstevel@tonic-gate 				if (flags & LF_REGEX) {
3047c478bd9Sstevel@tonic-gate 					match =
3057c478bd9Sstevel@tonic-gate 					    gmatch(&statnam[basedir_lastpos],
3067c478bd9Sstevel@tonic-gate 					    p);
3077c478bd9Sstevel@tonic-gate 				} else {
3087c478bd9Sstevel@tonic-gate 					match =
3097c478bd9Sstevel@tonic-gate 					    (strcmp(&statnam[basedir_lastpos],
3107c478bd9Sstevel@tonic-gate 					    p) == 0);
3117c478bd9Sstevel@tonic-gate 				}
3127c478bd9Sstevel@tonic-gate 				if (match) {
3137c478bd9Sstevel@tonic-gate 					/*
3147c478bd9Sstevel@tonic-gate 					 * Don't descend '.' directory
3157c478bd9Sstevel@tonic-gate 					 * but match it
3167c478bd9Sstevel@tonic-gate 					 */
3177c478bd9Sstevel@tonic-gate 					if (strcmp(dirent->d_name, ".") != 0) {
3187c478bd9Sstevel@tonic-gate 						do_list_item(dirent->d_name,
3197c478bd9Sstevel@tonic-gate 						    "*", flags, excld_lst,
3207c478bd9Sstevel@tonic-gate 						    dir, symlk_lst, func);
3217c478bd9Sstevel@tonic-gate 					} else {
3227c478bd9Sstevel@tonic-gate 						if ((depth-1) > do_dir) {
3237c478bd9Sstevel@tonic-gate 							do_dir = depth - 1;
3247c478bd9Sstevel@tonic-gate 						}
3257c478bd9Sstevel@tonic-gate 						(void) func(statnam,
3267c478bd9Sstevel@tonic-gate 						    dirent->d_name,
3277c478bd9Sstevel@tonic-gate 						    dir, depth);
3287c478bd9Sstevel@tonic-gate 					}
3297c478bd9Sstevel@tonic-gate 					retval = 1;
3307c478bd9Sstevel@tonic-gate 					if (unwind = discont_srch(flags, p)) {
3317c478bd9Sstevel@tonic-gate 						goto out;
3327c478bd9Sstevel@tonic-gate 					}
3337c478bd9Sstevel@tonic-gate 				}
3347c478bd9Sstevel@tonic-gate 				continue;
3357c478bd9Sstevel@tonic-gate 			}
3367c478bd9Sstevel@tonic-gate 			/*
3377c478bd9Sstevel@tonic-gate 			 * Don't descend '.' directory
3387c478bd9Sstevel@tonic-gate 			 */
3397c478bd9Sstevel@tonic-gate 			if (strcmp(dirent->d_name, ".") != 0) {
3407c478bd9Sstevel@tonic-gate 				do_list_item(dirent->d_name, p, flags,
3417c478bd9Sstevel@tonic-gate 				    excld_lst, dir, symlk_lst, func);
3427c478bd9Sstevel@tonic-gate 			}
3437c478bd9Sstevel@tonic-gate 			if (unwind) {
3447c478bd9Sstevel@tonic-gate 				goto out;
3457c478bd9Sstevel@tonic-gate 			}
3467c478bd9Sstevel@tonic-gate 			continue;
3477c478bd9Sstevel@tonic-gate 		}
3487c478bd9Sstevel@tonic-gate 		if (S_ISLNK(statbuf.st_mode)) {
3497c478bd9Sstevel@tonic-gate 			if (flags & LF_SYMLINK)
3507c478bd9Sstevel@tonic-gate 			    continue;
3517c478bd9Sstevel@tonic-gate #ifdef DEBUG
3527c478bd9Sstevel@tonic-gate 			printf("sym link : &statnam[basedir_lastpos] = %s\n",
3537c478bd9Sstevel@tonic-gate 			&statnam[basedir_lastpos]);
3547c478bd9Sstevel@tonic-gate 			printf("statbuf.st_mode = %o\n", statbuf.st_mode);
3557c478bd9Sstevel@tonic-gate 			printf("statnam = %s\n", statnam);
3567c478bd9Sstevel@tonic-gate #endif /* DEBUG */
3577c478bd9Sstevel@tonic-gate 			/*
3587c478bd9Sstevel@tonic-gate 			 * Symbolic link was explicitly specified or matches a
3597c478bd9Sstevel@tonic-gate 			 * regular expression in a LIST item. Thus we follow
3607c478bd9Sstevel@tonic-gate 			 * the link. Otherwise, just call 'func' for the link
3617c478bd9Sstevel@tonic-gate 			 * name.
3627c478bd9Sstevel@tonic-gate 			 */
3637c478bd9Sstevel@tonic-gate #ifdef DEBUG
3647c478bd9Sstevel@tonic-gate 			printf("depth = %d  sl_cnt = %d\n", depth, sl_cnt);
3657c478bd9Sstevel@tonic-gate 			fflush(stdout);
3667c478bd9Sstevel@tonic-gate #endif /* DEBUG */
3677c478bd9Sstevel@tonic-gate 			if ((depth-1) == sl_cnt) {
3687c478bd9Sstevel@tonic-gate 				if (flags & LF_REGEX) {
3697c478bd9Sstevel@tonic-gate 					match =
3707c478bd9Sstevel@tonic-gate 					    gmatch(&statnam[basedir_lastpos],
3717c478bd9Sstevel@tonic-gate 					    p);
3727c478bd9Sstevel@tonic-gate 				} else {
3737c478bd9Sstevel@tonic-gate 					match =
3747c478bd9Sstevel@tonic-gate 					    (strcmp(&statnam[basedir_lastpos],
3757c478bd9Sstevel@tonic-gate 					    p) == 0);
3767c478bd9Sstevel@tonic-gate 				}
3777c478bd9Sstevel@tonic-gate #ifdef DEBUG
3787c478bd9Sstevel@tonic-gate 				printf("match = %d\n", match);
3797c478bd9Sstevel@tonic-gate 				fflush(stdout);
3807c478bd9Sstevel@tonic-gate #endif /* DEBUG */
3817c478bd9Sstevel@tonic-gate 				if (match) {
3827c478bd9Sstevel@tonic-gate 					if ((depth-1) > do_dir) {
3837c478bd9Sstevel@tonic-gate 						do_dir = depth - 1;
3847c478bd9Sstevel@tonic-gate 					}
3857c478bd9Sstevel@tonic-gate 					retval = 1;
3867c478bd9Sstevel@tonic-gate 					(void) func(statnam, dirent->d_name,
3877c478bd9Sstevel@tonic-gate 					    dir, depth);
3887c478bd9Sstevel@tonic-gate 					sz = readlink(
3897c478bd9Sstevel@tonic-gate 					    statnam, linkbuf, MAXPATHLEN-1);
3907c478bd9Sstevel@tonic-gate #ifdef DEBUG
3917c478bd9Sstevel@tonic-gate 					printf("linkbuf = %s\n", linkbuf);
3927c478bd9Sstevel@tonic-gate 					printf("sz = %d\n", sz);
3937c478bd9Sstevel@tonic-gate 					fflush(stdout);
3947c478bd9Sstevel@tonic-gate #endif /* DEBUG */
3957c478bd9Sstevel@tonic-gate 					if (sz < 0) {
3967c478bd9Sstevel@tonic-gate 						continue;
3977c478bd9Sstevel@tonic-gate 					}
3987c478bd9Sstevel@tonic-gate 					linkbuf[sz] = '\0';
3997c478bd9Sstevel@tonic-gate 					process_symlk(linkbuf, statnam,
4007c478bd9Sstevel@tonic-gate 					    glastpos, symlk_lst, func);
4017c478bd9Sstevel@tonic-gate 					if (unwind = discont_srch(flags, p)) {
4027c478bd9Sstevel@tonic-gate 						goto out;
4037c478bd9Sstevel@tonic-gate 					}
4047c478bd9Sstevel@tonic-gate 				}
4057c478bd9Sstevel@tonic-gate 			}
4067c478bd9Sstevel@tonic-gate 			if ((depth-1) > sl_cnt) {
4077c478bd9Sstevel@tonic-gate 				if ((depth-1) > do_dir) {
4087c478bd9Sstevel@tonic-gate 					do_dir = depth - 1;
4097c478bd9Sstevel@tonic-gate 				}
4107c478bd9Sstevel@tonic-gate 				retval = 1;
4117c478bd9Sstevel@tonic-gate 				(void) func(statnam, dirent->d_name, dir,
4127c478bd9Sstevel@tonic-gate 				    depth);
4137c478bd9Sstevel@tonic-gate 				sz = readlink(statnam, linkbuf, MAXPATHLEN-1);
4147c478bd9Sstevel@tonic-gate #ifdef DEBUG
4157c478bd9Sstevel@tonic-gate 				printf("linkbuf = %s\n", linkbuf);
4167c478bd9Sstevel@tonic-gate 				printf("sz = %d\n", sz);
4177c478bd9Sstevel@tonic-gate 				fflush(stdout);
4187c478bd9Sstevel@tonic-gate #endif /* DEBUG */
4197c478bd9Sstevel@tonic-gate 				if (sz < 0) {
4207c478bd9Sstevel@tonic-gate 					continue;
4217c478bd9Sstevel@tonic-gate 				}
4227c478bd9Sstevel@tonic-gate 				linkbuf[sz] = '\0';
4237c478bd9Sstevel@tonic-gate 				process_symlk(linkbuf, statnam, glastpos,
4247c478bd9Sstevel@tonic-gate 				    symlk_lst, func);
4257c478bd9Sstevel@tonic-gate 				if (unwind = discont_srch(flags, p)) {
4267c478bd9Sstevel@tonic-gate 					goto out;
4277c478bd9Sstevel@tonic-gate 				}
4287c478bd9Sstevel@tonic-gate 			}
4297c478bd9Sstevel@tonic-gate 			continue;
4307c478bd9Sstevel@tonic-gate 		}
4317c478bd9Sstevel@tonic-gate 		/*
4327c478bd9Sstevel@tonic-gate 		 * File must be a regular file -
4337c478bd9Sstevel@tonic-gate 		 * Does it match the specified pattern?
4347c478bd9Sstevel@tonic-gate 		 */
4357c478bd9Sstevel@tonic-gate #ifdef DEBUG
4367c478bd9Sstevel@tonic-gate 		printf("reg file : &statnam[basedir_lastpos] = %s  p = %s\n",
4377c478bd9Sstevel@tonic-gate 			&statnam[basedir_lastpos], p);
4387c478bd9Sstevel@tonic-gate 		printf("statbuf.st_mode = %o\n", statbuf.st_mode);
4397c478bd9Sstevel@tonic-gate 		fflush(stdout);
4407c478bd9Sstevel@tonic-gate #endif /* DEBUG */
4417c478bd9Sstevel@tonic-gate 		if (flags & LF_REGEX) {
4427c478bd9Sstevel@tonic-gate 			match = gmatch(&statnam[basedir_lastpos], p);
4437c478bd9Sstevel@tonic-gate 		} else {
4447c478bd9Sstevel@tonic-gate 			match = (strcmp(&statnam[basedir_lastpos], p) == 0);
4457c478bd9Sstevel@tonic-gate 		}
4467c478bd9Sstevel@tonic-gate 		if (!match) {
4477c478bd9Sstevel@tonic-gate 			continue;
4487c478bd9Sstevel@tonic-gate 		}
4497c478bd9Sstevel@tonic-gate 		if ((depth - 1) > do_dir) {
4507c478bd9Sstevel@tonic-gate 			do_dir = depth - 1;
4517c478bd9Sstevel@tonic-gate 		}
4527c478bd9Sstevel@tonic-gate 		retval = 1;
4537c478bd9Sstevel@tonic-gate 		(void) func(statnam, dirent->d_name, dir, depth);
4547c478bd9Sstevel@tonic-gate 		/*
4557c478bd9Sstevel@tonic-gate 		 * If the file is an executable, check to see if shared
4567c478bd9Sstevel@tonic-gate 		 * libraries need to be packed.
4577c478bd9Sstevel@tonic-gate 		 */
4587c478bd9Sstevel@tonic-gate 		if (statbuf.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH)) {
4597c478bd9Sstevel@tonic-gate 			process_executable(statnam, func);
4607c478bd9Sstevel@tonic-gate 		}
4617c478bd9Sstevel@tonic-gate 
4627c478bd9Sstevel@tonic-gate 		if (unwind = discont_srch(flags, p)) {
4637c478bd9Sstevel@tonic-gate 			goto out;
4647c478bd9Sstevel@tonic-gate 		}
4657c478bd9Sstevel@tonic-gate 	}
4667c478bd9Sstevel@tonic-gate out:
4677c478bd9Sstevel@tonic-gate 	depth--;
4687c478bd9Sstevel@tonic-gate 	if (depth == 0) {
4697c478bd9Sstevel@tonic-gate 		unwind = 0;
4707c478bd9Sstevel@tonic-gate 	}
4717c478bd9Sstevel@tonic-gate 	statnam[glastpos] = '\0';
4727c478bd9Sstevel@tonic-gate 	if (do_dir) {
4737c478bd9Sstevel@tonic-gate 		do_dir--;
4747c478bd9Sstevel@tonic-gate #ifdef DEBUG
4757c478bd9Sstevel@tonic-gate 		printf("out:  call func\n");
4767c478bd9Sstevel@tonic-gate 		fflush(stdout);
4777c478bd9Sstevel@tonic-gate 		printf("out: statnam = %s\n", statnam);
4787c478bd9Sstevel@tonic-gate 		fflush(stdout);
4797c478bd9Sstevel@tonic-gate 		printf("out: &statnam[llastpos] = %s\n", &statnam[llastpos]);
4807c478bd9Sstevel@tonic-gate 		fflush(stdout);
4817c478bd9Sstevel@tonic-gate #endif /* DEBUG */
4827c478bd9Sstevel@tonic-gate 		if (func(statnam, &statnam[llastpos], parent_dir, depth) < 0) {
4837c478bd9Sstevel@tonic-gate 			do_dir = 0;
4847c478bd9Sstevel@tonic-gate 		}
4857c478bd9Sstevel@tonic-gate 	}
4867c478bd9Sstevel@tonic-gate 	glastpos = llastpos;
4877c478bd9Sstevel@tonic-gate 	if (diropn)
4887c478bd9Sstevel@tonic-gate 	    closedir(dir);
4897c478bd9Sstevel@tonic-gate 	return (retval);
4907c478bd9Sstevel@tonic-gate }
4917c478bd9Sstevel@tonic-gate 
4927c478bd9Sstevel@tonic-gate /*
4937c478bd9Sstevel@tonic-gate  * Count all the '/' characters in the string except for those
4947c478bd9Sstevel@tonic-gate  * in the first character position and last character position
4957c478bd9Sstevel@tonic-gate  * of the string.
4967c478bd9Sstevel@tonic-gate  */
4977c478bd9Sstevel@tonic-gate int
slash_cnt(char * str)4987c478bd9Sstevel@tonic-gate slash_cnt(char *str)
4997c478bd9Sstevel@tonic-gate {
5007c478bd9Sstevel@tonic-gate 	char *p = str;
5017c478bd9Sstevel@tonic-gate 	int len;
5027c478bd9Sstevel@tonic-gate 	int i;
5037c478bd9Sstevel@tonic-gate 	int count = 0;
5047c478bd9Sstevel@tonic-gate 
5057c478bd9Sstevel@tonic-gate #ifdef DEBUG
5067c478bd9Sstevel@tonic-gate 	printf("slash_cnt: str = %s", str);
5077c478bd9Sstevel@tonic-gate #endif /* DEBUG */
5087c478bd9Sstevel@tonic-gate 	/*
5097c478bd9Sstevel@tonic-gate 	 * NOTE //a, /a and ./a are the same
5107c478bd9Sstevel@tonic-gate 	 */
5117c478bd9Sstevel@tonic-gate 	if (*p == '.')
5127c478bd9Sstevel@tonic-gate 	    p++;
5137c478bd9Sstevel@tonic-gate 	while (*p == '/')
5147c478bd9Sstevel@tonic-gate 	    p++;
5157c478bd9Sstevel@tonic-gate 	len = strlen(str) - 1;
5167c478bd9Sstevel@tonic-gate 	for (i = 0; i < len; i++) {
5177c478bd9Sstevel@tonic-gate 		if (*p == '/') {
5187c478bd9Sstevel@tonic-gate 			count++;
5197c478bd9Sstevel@tonic-gate 			i--;
5207c478bd9Sstevel@tonic-gate 			while (*p == '/') {
5217c478bd9Sstevel@tonic-gate 				p++;
5227c478bd9Sstevel@tonic-gate 				i++;
5237c478bd9Sstevel@tonic-gate 			}
5247c478bd9Sstevel@tonic-gate 		} else {
5257c478bd9Sstevel@tonic-gate 			p++;
5267c478bd9Sstevel@tonic-gate 		}
5277c478bd9Sstevel@tonic-gate 	}
5287c478bd9Sstevel@tonic-gate #ifdef DEBUG
5297c478bd9Sstevel@tonic-gate 	printf("  count = %d\n", count);
5307c478bd9Sstevel@tonic-gate 	fflush(stdout);
5317c478bd9Sstevel@tonic-gate #endif /* DEBUG */
5327c478bd9Sstevel@tonic-gate 	return (count);
5337c478bd9Sstevel@tonic-gate }
5347c478bd9Sstevel@tonic-gate 
5357c478bd9Sstevel@tonic-gate /*
5367c478bd9Sstevel@tonic-gate  * For each directory in the path name, call 'func'.
5377c478bd9Sstevel@tonic-gate  */
5387c478bd9Sstevel@tonic-gate int
func_dir_path(char * path,int (* func)(char *,char *,DIR *,int))5397c478bd9Sstevel@tonic-gate func_dir_path(char *path, int (*func)(char *, char *, DIR *, int))
5407c478bd9Sstevel@tonic-gate {
5417c478bd9Sstevel@tonic-gate 	char *dnam;
5427c478bd9Sstevel@tonic-gate 	char *fnam;
5437c478bd9Sstevel@tonic-gate 	char *pathtmp;
5447c478bd9Sstevel@tonic-gate 	DIR *dir;
5457c478bd9Sstevel@tonic-gate 	char *get_fname(char *);
5467c478bd9Sstevel@tonic-gate 	char *get_dirname(char *);
5477c478bd9Sstevel@tonic-gate 	ENTRY hitem, *hitemp;
5487c478bd9Sstevel@tonic-gate 
5497c478bd9Sstevel@tonic-gate #ifdef DEBUG
5507c478bd9Sstevel@tonic-gate 	printf("func_dir_path: path = %s\n", path);
5517c478bd9Sstevel@tonic-gate 	fflush(stdout);
5527c478bd9Sstevel@tonic-gate #endif /* DEBUG */
5537c478bd9Sstevel@tonic-gate 	fnam = path;
5547c478bd9Sstevel@tonic-gate 	dnam = path;
5557c478bd9Sstevel@tonic-gate 	pathtmp = mstrdup(path);
5567c478bd9Sstevel@tonic-gate 	while (fnam != NULL) {
5577c478bd9Sstevel@tonic-gate 
5587c478bd9Sstevel@tonic-gate 		fnam = get_fname(dnam);
5597c478bd9Sstevel@tonic-gate 		dnam = get_dirname(dnam);
5607c478bd9Sstevel@tonic-gate 		if (fnam != (char *)0) {
5617c478bd9Sstevel@tonic-gate 			if (strcmp(fnam, "..") == 0) {
5627c478bd9Sstevel@tonic-gate 				free(pathtmp);
5637c478bd9Sstevel@tonic-gate 				pathtmp = mstrdup(dnam);
5647c478bd9Sstevel@tonic-gate 				continue;
5657c478bd9Sstevel@tonic-gate 			}
5667c478bd9Sstevel@tonic-gate 		}
5677c478bd9Sstevel@tonic-gate #ifdef DEBUG
5687c478bd9Sstevel@tonic-gate 		if (fnam != (char *)0) {
5697c478bd9Sstevel@tonic-gate 			printf("func_dir_path: fnam = %s\n", fnam);
5707c478bd9Sstevel@tonic-gate 		}
5717c478bd9Sstevel@tonic-gate 		printf("func_dir_path: dnam = %s  pathtmp = %s\n",
5727c478bd9Sstevel@tonic-gate 		    dnam,  pathtmp);
5737c478bd9Sstevel@tonic-gate 		fflush(stdout);
5747c478bd9Sstevel@tonic-gate #endif /* DEBUG */
5757c478bd9Sstevel@tonic-gate 
5767c478bd9Sstevel@tonic-gate 		hitem.key = mstrdup(pathtmp);
5777c478bd9Sstevel@tonic-gate 		hitem.data = 0;
5787c478bd9Sstevel@tonic-gate 		hitemp = hsearch(hitem, FIND);
5797c478bd9Sstevel@tonic-gate 		if (hitemp != NULL) {
5807c478bd9Sstevel@tonic-gate 			/*
5817c478bd9Sstevel@tonic-gate 			 * If hash item data is 0, item has not been packed.
5827c478bd9Sstevel@tonic-gate 			 * If hash item data is 1, item has been packed.
5837c478bd9Sstevel@tonic-gate 			 */
5847c478bd9Sstevel@tonic-gate #ifdef DEBUG
5857c478bd9Sstevel@tonic-gate 			printf("func_dir_path: key = %s hitemp->data = %x\n",
5867c478bd9Sstevel@tonic-gate 			    hitemp->key, hitemp->data);
5877c478bd9Sstevel@tonic-gate 			fflush(stdout);
5887c478bd9Sstevel@tonic-gate #endif /* DEBUG */
5897c478bd9Sstevel@tonic-gate 			if (hitemp->data == (char *)1)
5907c478bd9Sstevel@tonic-gate 			    break;
5917c478bd9Sstevel@tonic-gate 			hitemp->data = (char *)1;
5927c478bd9Sstevel@tonic-gate 		} else {
5937c478bd9Sstevel@tonic-gate 			hitem.key = mstrdup(pathtmp);
5947c478bd9Sstevel@tonic-gate 			hitem.data = (char *)1;
5957c478bd9Sstevel@tonic-gate 			if (hsearch(hitem, ENTER) == NULL) {
5967c478bd9Sstevel@tonic-gate 				fprintf(stderr,
5977c478bd9Sstevel@tonic-gate 				    gettext("cachefspack: hash table full\n"));
5987c478bd9Sstevel@tonic-gate 			}
5997c478bd9Sstevel@tonic-gate 		}
6007c478bd9Sstevel@tonic-gate 
6017c478bd9Sstevel@tonic-gate 		dir = opendir(dnam);
6027c478bd9Sstevel@tonic-gate 		if (dir != NULL) {
6037c478bd9Sstevel@tonic-gate 			if (func(pathtmp, fnam, dir, 0) < 0) {
6047c478bd9Sstevel@tonic-gate #ifdef DEBUG
6057c478bd9Sstevel@tonic-gate 				printf("func_dir_path: errno = %d\n", errno);
6067c478bd9Sstevel@tonic-gate 				fflush(stdout);
6077c478bd9Sstevel@tonic-gate #endif /* DEBUG */
6087c478bd9Sstevel@tonic-gate 				closedir(dir);
6097c478bd9Sstevel@tonic-gate 				return (-1);
6107c478bd9Sstevel@tonic-gate 			}
6117c478bd9Sstevel@tonic-gate 			closedir(dir);
6127c478bd9Sstevel@tonic-gate 		} else {
6137c478bd9Sstevel@tonic-gate 			printf(gettext("cachefspack:  error opening dir -"));
6147c478bd9Sstevel@tonic-gate 			printf("%s\n", dnam);
6157c478bd9Sstevel@tonic-gate 			fflush(stdout);
6167c478bd9Sstevel@tonic-gate 		}
6177c478bd9Sstevel@tonic-gate 
6187c478bd9Sstevel@tonic-gate 		free(pathtmp);
6197c478bd9Sstevel@tonic-gate 		pathtmp = mstrdup(dnam);
6207c478bd9Sstevel@tonic-gate 	}
6217c478bd9Sstevel@tonic-gate 	free(pathtmp);
6227c478bd9Sstevel@tonic-gate 	return (0);
6237c478bd9Sstevel@tonic-gate }
6247c478bd9Sstevel@tonic-gate void
process_symlk(char * lkpath,char * relpath,int rel_lastpos,struct item ** symlk,int (* func)(char *,char *,DIR *,int))6257c478bd9Sstevel@tonic-gate process_symlk(char *lkpath, char *relpath, int rel_lastpos,
6267c478bd9Sstevel@tonic-gate     struct item **symlk, int (*func)(char *, char *, DIR *, int))
6277c478bd9Sstevel@tonic-gate {
6287c478bd9Sstevel@tonic-gate 	struct stat64 lstatbuf;
6297c478bd9Sstevel@tonic-gate 	char *l;
6307c478bd9Sstevel@tonic-gate 	struct item *add_item(struct item *, char *, int);
6317c478bd9Sstevel@tonic-gate 	int len;
6327c478bd9Sstevel@tonic-gate 
6337c478bd9Sstevel@tonic-gate 	/*
6347c478bd9Sstevel@tonic-gate 	 * if the link has a relative pathname, append the name to
6357c478bd9Sstevel@tonic-gate 	 * current path.
6367c478bd9Sstevel@tonic-gate 	 */
6377c478bd9Sstevel@tonic-gate 	if (*lkpath != '/') {
6387c478bd9Sstevel@tonic-gate 		len = strlen(lkpath);
6397c478bd9Sstevel@tonic-gate 		if ((len + rel_lastpos + 2) > MAXPATHLEN) {
6407c478bd9Sstevel@tonic-gate 			fprintf(stderr, gettext("can't process sym link - %s"),
6417c478bd9Sstevel@tonic-gate 			    lkpath);
6427c478bd9Sstevel@tonic-gate 			return;
6437c478bd9Sstevel@tonic-gate 		}
6447c478bd9Sstevel@tonic-gate 		strcpy(&relpath[rel_lastpos], lkpath);
6457c478bd9Sstevel@tonic-gate 		l = relpath;
6467c478bd9Sstevel@tonic-gate 	} else {
6477c478bd9Sstevel@tonic-gate 		l = lkpath;
6487c478bd9Sstevel@tonic-gate 	}
6497c478bd9Sstevel@tonic-gate #ifdef DEBUG
6507c478bd9Sstevel@tonic-gate 	printf("process_symlk: lkpath = %s\n", lkpath);
6517c478bd9Sstevel@tonic-gate 	printf("process_symlk: l = %s\n", l);
6527c478bd9Sstevel@tonic-gate 	printf("lstatbuf.st_mode = %o\n", lstatbuf.st_mode);
6537c478bd9Sstevel@tonic-gate 	fflush(stdout);
6547c478bd9Sstevel@tonic-gate #endif /* DEBUG */
6557c478bd9Sstevel@tonic-gate 	if (lstat64(l, &lstatbuf) < 0) {
6567c478bd9Sstevel@tonic-gate 		fprintf(stderr, gettext("Can't lstat sym link - %s"), l);
6577c478bd9Sstevel@tonic-gate 		perror(" ");
6587c478bd9Sstevel@tonic-gate 		return;
6597c478bd9Sstevel@tonic-gate 	}
6607c478bd9Sstevel@tonic-gate 	if (S_ISDIR(lstatbuf.st_mode)) {
6617c478bd9Sstevel@tonic-gate 		*symlk = add_item(*symlk, l, 0);
6627c478bd9Sstevel@tonic-gate 	}
6637c478bd9Sstevel@tonic-gate 	if (S_ISREG(lstatbuf.st_mode)) {
6647c478bd9Sstevel@tonic-gate 		func_dir_path(l, func);
6657c478bd9Sstevel@tonic-gate 	}
6667c478bd9Sstevel@tonic-gate }
6677c478bd9Sstevel@tonic-gate 
668*47644099Sgt29601 int
discont_srch(int flags,char * pat)6697c478bd9Sstevel@tonic-gate discont_srch(int flags, char *pat)
6707c478bd9Sstevel@tonic-gate {
6717c478bd9Sstevel@tonic-gate 	char *wild;
6727c478bd9Sstevel@tonic-gate 
6737c478bd9Sstevel@tonic-gate #ifdef DEBUG
6747c478bd9Sstevel@tonic-gate 	printf("discont_srch: flags = %x  pat = %s\n", flags, pat);
6757c478bd9Sstevel@tonic-gate 	fflush(stdout);
6767c478bd9Sstevel@tonic-gate #endif /* DEBUG */
6777c478bd9Sstevel@tonic-gate 
6787c478bd9Sstevel@tonic-gate 	/*
6797c478bd9Sstevel@tonic-gate 	 * if patterns are NOT being matched as regular expressions
6807c478bd9Sstevel@tonic-gate 	 * we can have at most 1 match. We got it so quit.
6817c478bd9Sstevel@tonic-gate 	 */
6827c478bd9Sstevel@tonic-gate 	if ((flags & LF_REGEX) != LF_REGEX) {
6837c478bd9Sstevel@tonic-gate #ifdef DEBUG
6847c478bd9Sstevel@tonic-gate 		printf("discont_srch: ! LF_REGEX\n");
6857c478bd9Sstevel@tonic-gate 		fflush(stdout);
6867c478bd9Sstevel@tonic-gate #endif /* DEBUG */
6877c478bd9Sstevel@tonic-gate 		return (1);
6887c478bd9Sstevel@tonic-gate 	}
6897c478bd9Sstevel@tonic-gate 	/*
6907c478bd9Sstevel@tonic-gate 	 * if the pattern does not contain wildcard characters and
6917c478bd9Sstevel@tonic-gate 	 * we have found a match we are done.
6927c478bd9Sstevel@tonic-gate 	 */
6937c478bd9Sstevel@tonic-gate 	if (WILDCARD(wild, pat) == NULL) {
6947c478bd9Sstevel@tonic-gate #ifdef DEBUG
6957c478bd9Sstevel@tonic-gate 		printf("discont_srch: wild = %x\n", wild);
6967c478bd9Sstevel@tonic-gate 		fflush(stdout);
6977c478bd9Sstevel@tonic-gate #endif /* DEBUG */
6987c478bd9Sstevel@tonic-gate 		return (1);
6997c478bd9Sstevel@tonic-gate 	}
7007c478bd9Sstevel@tonic-gate 	return (0);
7017c478bd9Sstevel@tonic-gate }
7027c478bd9Sstevel@tonic-gate 
7037c478bd9Sstevel@tonic-gate #ifdef DEBUG
prtitem(char * str,struct item * hd)7047c478bd9Sstevel@tonic-gate prtitem(char *str, struct item *hd)
7057c478bd9Sstevel@tonic-gate {
7067c478bd9Sstevel@tonic-gate 	struct item *p = hd->i_next;
7077c478bd9Sstevel@tonic-gate 
7087c478bd9Sstevel@tonic-gate 	printf("\n%s\n\n", str);
7097c478bd9Sstevel@tonic-gate 	while (p != (struct item *)0) {
7107c478bd9Sstevel@tonic-gate 		printf("str = %s\n", p->i_str);
7117c478bd9Sstevel@tonic-gate 		p = p->i_next;
7127c478bd9Sstevel@tonic-gate 	}
7137c478bd9Sstevel@tonic-gate }
7147c478bd9Sstevel@tonic-gate #endif /* DEBUG */
715