1 /* @(#)create.c	1.162 20/07/08 Copyright 1985, 1995, 2001-2020 J. Schilling */
2 #include <schily/mconfig.h>
3 #ifndef lint
4 static	UConst char sccsid[] =
5 	"@(#)create.c	1.162 20/07/08 Copyright 1985, 1995, 2001-2020 J. Schilling";
6 #endif
7 /*
8  *	Copyright (c) 1985, 1995, 2001-2020 J. Schilling
9  */
10 /*
11  * The contents of this file are subject to the terms of the
12  * Common Development and Distribution License, Version 1.0 only
13  * (the "License").  You may not use this file except in compliance
14  * with the License.
15  *
16  * See the file CDDL.Schily.txt in this distribution for details.
17  * A copy of the CDDL is also available via the Internet at
18  * http://www.opensource.org/licenses/cddl1.txt
19  *
20  * When distributing Covered Code, include this CDDL HEADER in each
21  * file and include the License file CDDL.Schily.txt from this distribution.
22  */
23 
24 #include <schily/stdio.h>
25 #include "star.h"
26 #include "props.h"
27 #include "table.h"
28 #include <schily/errno.h>	/* XXX seterrno() is better JS */
29 #include <schily/standard.h>
30 #include <schily/stdlib.h>
31 #include <schily/unistd.h>
32 #include <schily/dirent.h>
33 #include <schily/string.h>
34 #include <schily/jmpdefs.h>	/* For __fjmalloc() */
35 #define	GT_COMERR		/* #define comerr gtcomerr */
36 #define	GT_ERROR		/* #define error gterror   */
37 #include <schily/schily.h>
38 #include <schily/idcache.h>
39 #include "restore.h"
40 #ifdef	USE_FIND
41 #include <schily/fcntl.h>	/* For AT_FDCWD */
42 #include <schily/stat.h>	/* Fuer stat_to_info() in starsubs.h */
43 #include <schily/walk.h>
44 #include <schily/find.h>
45 #endif
46 #include "starsubs.h"
47 #include "checkerr.h"
48 #include "fifo.h"
49 #include <schily/fetchdir.h>
50 
51 #ifdef	USE_ACL
52 
53 #ifdef	OWN_ACLTEXT
54 #if	defined(UNIXWARE) && defined(HAVE_ACL)
55 #define	HAVE_SUN_ACL
56 #define	HAVE_ANY_ACL
57 #endif
58 #endif
59 /*
60  * HAVE_ANY_ACL currently includes HAVE_POSIX_ACL and HAVE_SUN_ACL.
61  * This definition must be in sync with the definition in acl_unix.c
62  * As USE_ACL is used in star.h, we are not allowed to change the
63  * value of USE_ACL before we did include star.h or we may not include
64  * star.h at all.
65  * HAVE_HP_ACL is currently not included in HAVE_ANY_ACL.
66  */
67 #ifndef	HAVE_ANY_ACL
68 #undef	USE_ACL		/* Do not try to get or set ACLs */
69 #endif
70 #endif
71 
72 struct pdirs {
73 	struct pdirs	*p_last;
74 	dev_t		p_dev;
75 	ino_t		p_ino;
76 };
77 
78 typedef	struct	lname {
79 	struct	lname	*l_lnext;	/* Next in list */
80 		char	l_lname[1];	/* actually longer */
81 } LNAME;
82 
83 typedef	struct	links {
84 	struct	links	*l_next;	/* Next in list */
85 	struct	lname	*l_lnames;	/* Link names for SVr4 cpio */
86 		ino_t	l_ino;		/* Inode number (st_ino) */
87 		dev_t	l_dev;		/* Filesys number (st_dev) */
88 		Ulong	l_linkno;	/* Link serial number in compl. list */
89 		long	l_nlink;	/* Link count for file */
90 		short	l_namlen;	/* strlen(l_name) */
91 		Uchar	l_flags;	/* Flags (see below) */
92 		char	l_name[1];	/* actually longer */
93 } LINKS;
94 
95 #define	L_ISDIR		1		/* This entry refers to a directory  */
96 #define	L_ISLDIR	2		/* A dir, hard linked to another dir */
97 #define	L_DATA		4		/* SVr4 cpio file data encountered   */
98 
99 #define	L_HSIZE		256		/* must be a power of two */
100 
101 #define	l_hash(info)	(((info)->f_ino + (info)->f_dev) & (L_HSIZE-1))
102 
103 LOCAL	LINKS	*links[L_HSIZE];
104 
105 extern	FILE	*vpr;
106 extern	FILE	*listf;
107 
108 extern	BOOL	pkglist;
109 extern	BOOL	multivol;
110 extern	long	hdrtype;
111 extern	BOOL	tape_isreg;
112 extern	dev_t	tape_dev;
113 extern	ino_t	tape_ino;
114 #define	is_tape(info)		((info)->f_dev == tape_dev && (info)->f_ino == tape_ino)
115 
116 extern	long	bufsize;
117 extern	char	*bigptr;
118 
119 extern	BOOL	havepat;
120 extern	dev_t	curfs;
121 extern	Ullong	maxsize;
122 extern	struct timespec	Newer;
123 extern	Ullong	tsize;
124 extern	BOOL	prblockno;
125 extern	BOOL	debug;
126 extern	int	dumplevel;
127 extern	int	verbose;
128 extern	BOOL	silent;
129 extern	BOOL	readnull;
130 extern	BOOL	cflag;
131 extern	BOOL	uflag;
132 extern	BOOL	nodir;
133 extern	BOOL	acctime;
134 extern	BOOL	dirmode;
135 extern	BOOL	paxfollow;
136 extern	BOOL	doacl;
137 extern	BOOL	doxattr;
138 extern	BOOL	dolxattr;
139 extern	BOOL	nodesc;
140 extern	BOOL	nomount;
141 extern	BOOL	interactive;
142 extern	BOOL	nospec;
143 extern	int	Fflag;
144 extern	BOOL	abs_path;
145 extern	BOOL	nowarn;
146 extern	BOOL	match_tree;
147 extern	BOOL	force_hole;
148 extern	BOOL	sparse;
149 extern	BOOL	Ctime;
150 extern	BOOL	nodump;
151 extern	BOOL	nullout;
152 extern	BOOL	linkdata;
153 extern	BOOL	link_dirs;
154 extern	BOOL	dodump;
155 extern	BOOL	dometa;
156 extern	BOOL	dumpmeta;
157 extern	BOOL	lowmem;
158 extern	BOOL	do_subst;
159 
160 #ifdef	USE_FIND
161 extern	BOOL	dofind;
162 #endif
163 
164 extern	int	intr;
165 
166 /*
167  * Variables that control overwriting the stat() struct members
168  * controlled by the pkglist= option.
169  */
170 LOCAL	BOOL	statmod = FALSE;
171 LOCAL	uid_t	statuid = _BAD_UID;
172 LOCAL	gid_t	statgid = _BAD_GID;
173 LOCAL	mode_t	statmode = _BAD_MODE;
174 
175 EXPORT	void	checklinks	__PR((void));
176 LOCAL	int	take_file	__PR((char *name, FINFO *info));
177 EXPORT	ssize_t	_fileread	__PR((int *fp, void *buf, size_t len));
178 EXPORT	void	create		__PR((char *name, BOOL Hflag, BOOL forceadd));
179 LOCAL	void	createi		__PR((char *sname, char *name, int namlen,
180 					FINFO *info, pathstore_t *pathp,
181 					struct pdirs *last));
182 EXPORT	void	createlist	__PR((struct WALK *state));
183 LOCAL	BOOL	get_metainfo	__PR((char *line));
184 EXPORT	BOOL	read_symlink	__PR((char *sname, char *name, FINFO *info, TCB *ptb));
185 LOCAL	LINKS	*find_link	__PR((FINFO *info));
186 EXPORT	BOOL	last_cpio_link	__PR((FINFO *info));
187 EXPORT	BOOL	xcpio_link	__PR((FINFO *info));
188 LOCAL	BOOL	acpio_link	__PR((FINFO *info));
189 EXPORT	void	flushlinks	__PR((void));
190 LOCAL	void	flush_link	__PR((LINKS *lp));
191 EXPORT	BOOL	read_link	__PR((char *name, int namlen, FINFO *info,
192 								TCB *ptb));
193 LOCAL	ssize_t	nullread	__PR((void *vp, char *cp, size_t amt));
194 EXPORT	void	put_file	__PR((int *fp, FINFO *info));
195 EXPORT	void	cr_file		__PR((FINFO *info,
196 					ssize_t (*)(void *, char *, size_t),
197 					void *arg, long amt, char *text));
198 LOCAL	void	put_dir		__PR((char *sname, char *dname, int namlen,
199 					FINFO *info, TCB *ptb,
200 					pathstore_t *pathp, struct pdirs *last));
201 LOCAL	void	toolong		__PR((char *dname, char	*name, size_t len));
202 LOCAL	BOOL	checkdirexclude	__PR((char *sname, char *name, int namlen, FINFO *info));
203 LOCAL	BOOL	checkexclude	__PR((char *sname, char *name, int namlen, FINFO *info));
204 
205 #ifdef	USE_FIND
206 EXPORT	int	walkfunc	__PR((char *nm, struct stat *fs, int type, struct WALK *state));
207 LOCAL	void	findcreate	__PR((char *name, struct WALK *state));
208 #endif
209 
210 EXPORT void
checklinks()211 checklinks()
212 {
213 	register LINKS	*lp;
214 	register int	i;
215 	register int	used	= 0;
216 	register int	curlen;
217 	register int	maxlen	= 0;
218 	register int	nlinks	= 0;
219 	register int	ndirs	= 0;
220 	register int	nldirs	= 0;
221 
222 	for (i = 0; i < L_HSIZE; i++) {
223 		if (links[i] == (LINKS *)NULL)
224 			continue;
225 
226 		curlen = 0;
227 		used++;
228 
229 		for (lp = links[i]; lp != (LINKS *)NULL; lp = lp->l_next) {
230 			curlen++;
231 			nlinks++;
232 			if ((lp->l_flags & L_ISDIR) != 0) {
233 				ndirs++;
234 				if ((lp->l_flags & L_ISLDIR) != 0)
235 					nldirs++;
236 			} else if (lp->l_nlink != 0) {
237 				/*
238 				 * The fact that UNIX uses '.' and '..' as hard
239 				 * links to directories on all known file
240 				 * systems is a design bug. It makes it hard to
241 				 * find hard links to directories. Note that
242 				 * POSIX neither requires '.' and '..' to be
243 				 * implemented as hard links nor that these
244 				 * directories are physical present in the
245 				 * directory content.
246 				 * As it is hard to find all links (we would
247 				 * need to stat all directories as well as all
248 				 * '.' and '..' entries, we only warn for non
249 				 * directories.
250 				 */
251 				if (cflag &&
252 				    !errhidden(E_MISSLINK, lp->l_name)) {
253 					if (!errwarnonly(E_MISSLINK, lp->l_name))
254 						xstats.s_misslinks++;
255 					errmsgno(EX_BAD,
256 						"Missing links to '%s'.\n",
257 								lp->l_name);
258 					(void) errabort(E_MISSLINK, lp->l_name,
259 									TRUE);
260 				}
261 			}
262 		}
263 		if (maxlen < curlen)
264 			maxlen = curlen;
265 	}
266 	if (debug) {
267 		if (link_dirs) {
268 			errmsgno(EX_BAD, "entries: %d hashents: %d/%d maxlen: %d\n",
269 						nlinks, used, L_HSIZE, maxlen);
270 			errmsgno(EX_BAD, "hardlinks total: %d linked dirs: %d/%d linked files: %d \n",
271 						nlinks+nldirs-ndirs, nldirs, ndirs, nlinks-ndirs);
272 		} else {
273 			errmsgno(EX_BAD, "hardlinks: %d hashents: %d/%d maxlen: %d\n",
274 						nlinks, used, L_HSIZE, maxlen);
275 		}
276 	}
277 }
278 
279 /*
280  * Returns:
281  *	TRUE	take file
282  *	FALSE	do not take file
283  *	-1	pattern did not match
284  */
285 LOCAL int
take_file(name,info)286 take_file(name, info)
287 	register char	*name;
288 	register FINFO	*info;
289 {
290 	if ((info->f_flags & F_FORCE_ADD) != 0)
291 		return (TRUE);
292 	if (nodump && (info->f_flags & F_NODUMP) != 0)
293 		return (FALSE);
294 
295 	if (havepat && !match(name)) {
296 		return (-1);
297 			/* Bei Directories ist f_size == 0 */
298 	} else if (maxsize && info->f_size > maxsize) {
299 		return (FALSE);
300 	} else if (dumplevel > 0) {
301 		/*
302 		 * For now, we cannot reliably deal with sub-second granularity
303 		 * on all platforms. For this reason, we let some files be on
304 		 * two incrementals to make sure not to miss them completely.
305 		 */
306 		if (info->f_mtime >= Newer.tv_sec) {
307 			/* EMPTY */
308 			;
309 		} else if (info->f_ctime >= Newer.tv_sec) {
310 			if (dumpmeta)
311 				info->f_xftype = XT_META;
312 		} else {
313 			return (FALSE);
314 		}
315 
316 	} else if (Newer.tv_sec && (Ctime ? info->f_ctime:info->f_mtime) <=
317 								Newer.tv_sec) {
318 		/*
319 		 * First the easy case: Don't take file if seconds are
320 		 * less than in the reference file.
321 		 */
322 		if ((Ctime ? info->f_ctime:info->f_mtime) < Newer.tv_sec)
323 			return (FALSE);
324 		/*
325 		 * If we do not have nanoseconds, we are done.
326 		 */
327 		if ((info->f_flags & F_NSECS) == 0)
328 			return (FALSE);
329 		/*
330 		 * Here we know that we have nanoseconds and that seconds
331 		 * are equal, so finally check nanoseconds.
332 		 */
333 		if ((Ctime ? info->f_cnsec:info->f_mnsec) <= Newer.tv_nsec)
334 			return (FALSE);
335 	} else if (uflag && !update_newer(info)) {
336 		return (FALSE);
337 	} else if (!multivol &&
338 		    tsize > 0 && tsize < (tarblocks(info->f_size)+1+2)) {
339 		if (!errhidden(E_FILETOOBIG, name)) {
340 			if (!errwarnonly(E_FILETOOBIG, name))
341 				xstats.s_toobig++;
342 			errmsgno(EX_BAD,
343 			"'%s' does not fit on tape. Not dumped.\n",
344 								name);
345 			(void) errabort(E_FILETOOBIG, name, TRUE);
346 		}
347 		return (FALSE);
348 	} else if (props.pr_maxsize > 0 && info->f_size > props.pr_maxsize) {
349 		if (!errhidden(E_FILETOOBIG, name)) {
350 			if (!errwarnonly(E_FILETOOBIG, name))
351 				xstats.s_toobig++;
352 			errmsgno(EX_BAD,
353 			"'%s' file too big for current mode. Not dumped.\n",
354 								name);
355 			(void) errabort(E_FILETOOBIG, name, TRUE);
356 		}
357 		return (FALSE);
358 	} else if (pr_unsuptype(info)) {
359 		if (!errhidden(E_SPECIALFILE, name)) {
360 			if (!errwarnonly(E_SPECIALFILE, name))
361 				xstats.s_isspecial++;
362 			errmsgno(EX_BAD,
363 			"'%s' unsupported file type '%s'. Not dumped.\n",
364 				name,  XTTONAME(info->f_xftype));
365 			(void) errabort(E_SPECIALFILE, name, TRUE);
366 		}
367 		return (FALSE);
368 	} else if (is_special(info) && nospec) {
369 		if (!errhidden(E_SPECIALFILE, name)) {
370 			if (!errwarnonly(E_SPECIALFILE, name))
371 				xstats.s_isspecial++;
372 			errmsgno(EX_BAD,
373 			"'%s' is not a file. Not dumped.\n", name);
374 			(void) errabort(E_SPECIALFILE, name, TRUE);
375 		}
376 		return (FALSE);
377 	} else if (tape_isreg && is_tape(info)) {
378 		errmsgno(EX_BAD, "'%s' is the archive. Not dumped.\n", name);
379 		return (FALSE);
380 	}
381 	if (is_file(info) && dometa) {
382 		/*
383 		 * This is the right place for this code although it does not
384 		 * look correct. Later in star-1.5 we decide here, based on
385 		 * mtime and ctime of the file, whether we archive a file at
386 		 * all and whether we only add the file's metadata.
387 		 */
388 		info->f_xftype = XT_META;
389 		if (pr_unsuptype(info)) {
390 			if (!errhidden(E_SPECIALFILE, name)) {
391 				if (!errwarnonly(E_SPECIALFILE, name))
392 					xstats.s_isspecial++;
393 				errmsgno(EX_BAD,
394 				"'%s' unsupported file type '%s'. Not dumped.\n",
395 				name,  XTTONAME(info->f_xftype));
396 				(void) errabort(E_SPECIALFILE, name, TRUE);
397 			}
398 			return (FALSE);
399 		}
400 	}
401 #ifdef	USE_ACL
402 	/*
403 	 * If we return (FALSE) here, the file would not be archived at all.
404 	 * This is not what we want, so ignore return code from get_acls().
405 	 */
406 	if (doacl)
407 		(void) get_acls(info);
408 #endif  /* USE_ACL */
409 #ifdef	USE_XATTR
410 	if (dolxattr)
411 		(void) get_xattr(info);
412 #endif
413 	return (TRUE);
414 }
415 
416 ssize_t
_fileread(fp,buf,len)417 _fileread(fp, buf, len)
418 	register int	*fp;
419 	void	*buf;
420 	size_t	len;
421 {
422 	register int		fd = *fp;
423 	register ssize_t	ret;
424 		int		errcnt = 0;
425 
426 retry:
427 	while ((ret = read(fd, buf, len)) < 0 && geterrno() == EINTR)
428 		/* LINTED */
429 		;
430 	if (ret < 0 && geterrno() == EINVAL && ++errcnt < 100) {
431 		off_t oo;
432 		off_t si;
433 
434 		/*
435 		 * Work around the problem that we cannot read()
436 		 * if the buffer crosses 2 GB in non large file mode.
437 		 */
438 		oo = lseek(fd, (off_t)0, SEEK_CUR);
439 		if (oo == (off_t)-1)
440 			return (ret);
441 		si = lseek(fd, (off_t)0, SEEK_END);
442 		if (si == (off_t)-1)
443 			return (ret);
444 		if (lseek(fd, oo, SEEK_SET) == (off_t)-1)
445 			return (ret);
446 		if (oo >= si) {	/* EOF */
447 			ret = 0;
448 		} else if ((si - oo) <= len) {
449 			len = si - oo;
450 			goto retry;
451 		}
452 	}
453 	return (ret);
454 }
455 
456 EXPORT void
create(name,Hflag,forceadd)457 create(name, Hflag, forceadd)
458 	register char	*name;
459 		BOOL	Hflag;
460 		BOOL	forceadd;
461 {
462 		FINFO	finfo;
463 	register FINFO	*info	= &finfo;
464 		BOOL	opaxfollow = paxfollow;	/* paxfollow supersedes follow */
465 
466 	if (name[0] == '.' && name[1] == '/') {
467 		for (name++; name[0] == '/'; name++)
468 			/* LINTED */
469 			;
470 	}
471 	if (name[0] == '\0')
472 		name = ".";
473 	if (Hflag)
474 		paxfollow = Hflag;
475 	if (!getinfo(name, info)) {
476 		paxfollow = opaxfollow;
477 		if (!errhidden(E_STAT, name)) {
478 			if (!errwarnonly(E_STAT, name))
479 				xstats.s_staterrs++;
480 			errmsg("Cannot stat '%s'.\n", name);
481 			(void) errabort(E_STAT, name, TRUE);
482 		}
483 		return;
484 	}
485 	if (forceadd)
486 		info->f_flags |= F_FORCE_ADD;
487 	paxfollow = opaxfollow;
488 	createi(name, name, strlen(name), info,
489 		(pathstore_t *)0, (struct pdirs *)0);
490 }
491 
492 LOCAL void
createi(sname,name,namlen,info,pathp,last)493 createi(sname, name, namlen, info, pathp, last)
494 		char	*sname;
495 	register char	*name;
496 		int	namlen;
497 	register FINFO	*info;
498 		pathstore_t *pathp;
499 		struct pdirs *last;
500 {
501 		char	lname[PATH_MAX+1];  /* This limit cannot be overruled */
502 		TCB	tb;
503 	register TCB	*ptb		= &tb;
504 		int	fd		= -1;
505 		BOOL	was_link	= FALSE;
506 		BOOL	do_sparse	= FALSE;
507 
508 	if (hash_xlookup(name))
509 		return;
510 
511 	info->f_sname = sname;
512 	info->f_name = name;	/* XXX Das ist auch in getinfo !!!?!!! */
513 	info->f_namelen = namlen;
514 	if (Fflag > 0 && !checkexclude(sname, name, namlen, info))
515 		return;
516 
517 #ifdef	nonono_NICHT_BEI_CREATE	/* XXX */
518 	if (!abs_path &&	/* XXX VVV siehe skip_slash() */
519 		(info->f_name[0] == '/' /* || info->f_lname[0] == '/' */)) {
520 		skip_slash(info);
521 		info->f_namelen -= info->f_name - name;
522 		if (info->f_namelen == 0) {
523 			info->f_name = "./";
524 			info->f_namelen = 2;
525 		}
526 		/* XXX das gleiche mit f_lname !!!!! */
527 	}
528 #endif	/* nonono_NICHT_BEI_CREATE	XXX */
529 	info->f_lname = lname;	/* XXX nur �bergangsweise!!!!! */
530 	info->f_lnamelen = 0;
531 
532 	if (prblockno)
533 		(void) tblocks();		/* set curblockno */
534 
535 	if (do_subst && subst(info)) {
536 		if (info->f_name[0] == '\0') {
537 			if (verbose)
538 			fgtprintf(vpr,
539 				"'%s' substitutes to null string, skipping ...\n",
540 							name);
541 			return;
542 		}
543 	}
544 
545 	if (statmod) {
546 		if (statmode != _BAD_MODE)
547 			info->f_mode = statmode;
548 		if (statuid != _BAD_UID)
549 			info->f_uid = statuid;
550 		if (statgid != _BAD_GID)
551 			info->f_gid = statgid;
552 	}
553 
554 	if (verbose <= 1 &&
555 	    !(dirmode && is_dir(info)) &&
556 				(info->f_namelen <= props.pr_maxsname)) {
557 		/*
558 		 * Allocate TCB from the buffer to avoid copying TCB
559 		 * in the most frequent case.
560 		 * If we are writing directories after the files they
561 		 * contain, we cannot allocate the space for tcb
562 		 * from the buffer.
563 		 * With very long names we will have to write out
564 		 * other data before we can write the TCB, so we cannot
565 		 * alloc tcb from buffer too.
566 		 * If we are creating a long listing while archiving, the
567 		 * TCB will be overwritten by info_to_xhdr() and this would
568 		 * overwrite username/groupname that is later needed for
569 		 * vprint(), so we cannot allocate TCB from the buffer here.
570 		 */
571 		if ((ptb = (TCB *)get_block(props.pr_hdrsize)) == NULL)
572 			ptb = &tb;
573 		else
574 			info->f_flags |= F_TCB_BUF;
575 	}
576 	info->f_tcb = ptb;
577 	if ((props.pr_flags & PR_CPIO) == 0)
578 		filltcb(ptb);
579 	if (!name_to_tcb(info, ptb))	/* Name too long */
580 		return;
581 
582 #ifndef	__PRE_CPIO__
583 	if (is_symlink(info) && !read_symlink(sname, name, info, ptb)) {
584 		return;
585 	}
586 #endif
587 	info_to_tcb(info, ptb);
588 	if (is_dir(info)) {
589 		/*
590 		 * If we have been requested to check for hard linked
591 		 * directories, first look for possible hard links.
592 		 */
593 		if (link_dirs && /* info->f_nlink > 1 && */ read_link(name, namlen, info, ptb))
594 			was_link = TRUE;
595 
596 		if (was_link && !is_link(info))	/* link name too long */
597 			return;
598 
599 		if (was_link && take_file(name, info) > 0) {
600 			put_tcb(ptb, info);
601 			vprint(info);
602 		} else {
603 			put_dir(sname, name, namlen, info, ptb, pathp, last);
604 		}
605 	} else if (take_file(name, info) <= 0) {	/* < TRUE */
606 		return;
607 	} else if (interactive && !ia_change(ptb, info)) {
608 		fgtprintf(vpr, "Skipping ...\n");
609 #ifdef	__PRE_CPIO__
610 	} else if (is_symlink(info) && !read_symlink(sname, name, info, ptb)) {
611 		/* EMPTY */
612 		;
613 #endif
614 	} else if (is_meta(info)) {
615 		/*
616 		 * XXX Currently only TAR supports meta files.
617 		 * XXX If we ever change this, we may need to remove the
618 		 * XXX ptb->dbuf references here.
619 		 */
620 		if (info->f_nlink > 1 && read_link(name, namlen, info, ptb))
621 			was_link = TRUE;
622 
623 		if (was_link && !is_link(info))	/* link name too long */
624 			return;
625 
626 		if (!was_link) {
627 			/*
628 			 * XXX We definitely do not want that other tar
629 			 * XXX implementations are able to read tar archives
630 			 * XXX that contain meta files.
631 			 * XXX If a tar implementation that does not understand
632 			 * XXX meta files extracts archives with meta files,
633 			 * XXX it will most likely destroy old files on disk.
634 			 */
635 			ptb->dbuf.t_linkflag = LF_META;
636 			info->f_flags &= ~F_SPLIT_NAME;
637 			if (ptb->dbuf.t_prefix[0] != '\0')
638 				fillbytes(ptb->dbuf.t_prefix, props.pr_maxprefix, '\0');
639 			if (props.pr_flags & PR_XHDR)
640 				info->f_xflags |= XF_PATH;
641 			else
642 				info->f_flags |= F_LONGNAME;
643 			ptb->dbuf.t_name[0] = 0;	/* Hide P-1988 name */
644 			info_to_tcb(info, ptb);
645 		}
646 		put_tcb(ptb, info);
647 		vprint(info);
648 		return;
649 
650 	} else if (is_file(info) && info->f_size != 0 && !nullout &&
651 				(fd = _lfileopen(sname, "rb")) < 0) {
652 		if (!errhidden(E_OPEN, name)) {
653 			if (!errwarnonly(E_OPEN, name))
654 				xstats.s_openerrs++;
655 			errmsg("Cannot open '%s'.\n", name);
656 			(void) errabort(E_OPEN, name, TRUE);
657 		}
658 	} else {
659 		if (info->f_nlink > 1 && read_link(name, namlen, info, ptb) &&
660 		    !linkdata) {
661 			was_link = TRUE;
662 		}
663 		if (was_link && !is_link(info))	{ /* link name too long */
664 			if (fd >= 0)
665 				close(fd);
666 			return;
667 		}
668 		/*
669 		 * Special treatment for the idiosyncratic way of dealing with
670 		 * hard links in the SVr4 CRC cpio archive format.
671 		 * The link count is handled by calling read_link() in
672 		 * cpiotcb_to_info() before.
673 		 */
674 		if ((props.pr_flags & PR_SV_CPIO_LINKS) != 0 &&
675 		    info->f_nlink > 1) {
676 			if (!last_cpio_link(info)) {	/* Ign. all but last */
677 				if (fd >= 0)
678 					close(fd);
679 				return;
680 			}
681 			if (acpio_link(info)) {		/* Now extract all   */
682 				put_file(&fd, info);
683 				goto out;
684 			}
685 			/*
686 			 * If the link count is increasing, do it the same way
687 			 * as SVr4 cpio and archive the rest as plain files.
688 			 */
689 			if (is_file(info))
690 				info->f_rsize = info->f_size;
691 			info->f_xftype = info->f_rxftype;
692 		}
693 
694 		if (!is_file(info) || was_link || info->f_rsize == 0) {
695 			/*
696 			 * Don't dump the content of hardlinks and empty files.
697 			 * Hardlinks currently have f_rsize == 0 !
698 			 */
699 			put_tcb(ptb, info);
700 			vprint(info);
701 			if (fd >= 0)
702 				close(fd);
703 			return;
704 		}
705 
706 		/*
707 		 * In case we like to do sparse file handling via SEEK_HOLE we need
708 		 * an open fd in order to check for a sparse file.
709 		 */
710 		do_sparse = sparse && (props.pr_flags & PR_SPARSE);
711 		if (do_sparse && nullout &&
712 				(fd = _lfileopen(sname, "rb")) < 0) {
713 			if (!errhidden(E_OPEN, name)) {
714 				if (!errwarnonly(E_OPEN, name))
715 					xstats.s_openerrs++;
716 				errmsg("Cannot open '%s'.\n", name);
717 				(void) errabort(E_OPEN, name, TRUE);
718 			}
719 			return;
720 		}
721 
722 		if (do_sparse && sparse_file(&fd, info)) {
723 			if (!silent)
724 				error("'%s' is sparse\n", info->f_name);
725 			put_sparse(&fd, info);
726 		} else if (do_sparse && force_hole) {
727 			/*
728 			 * Treat all files as sparse when -force-hole
729 			 * option is given. Files that do not contain
730 			 * any zeroed region will however still be
731 			 * archived as plain files by put_sparse().
732 			 */
733 			put_sparse(&fd, info);
734 		} else {
735 			put_tcb(ptb, info);
736 			vprint(info);
737 			put_file(&fd, info);
738 		}
739 		/*
740 		 * Reset access time of file.
741 		 * This is important when using star for dumps.
742 		 * N.B. this has been done after fclose()
743 		 * before _FIOSATIME has been used.
744 		 *
745 		 * If f == NULL, the file has not been accessed for read
746 		 * and access time need not be reset.
747 		 */
748 out:
749 		if (acctime && fd >= 0)
750 			rs_acctime(fd, info);
751 		if (fd >= 0)
752 			close(fd);
753 	}
754 }
755 
756 EXPORT void
createlist(state)757 createlist(state)
758 	struct WALK	*state;
759 {
760 	register int	nlen;
761 		char	*name;
762 		size_t	nsize = PATH_MAX;
763 
764 	/*
765 	 * We need at least PATH_MAX+1 and add 512 to get better messages below
766 	 */
767 	name = ___malloc(nsize, "name buffer");
768 
769 	for (nlen = 1; nlen >= 0; ) {
770 		if ((nlen = getdelim(&name, &nsize,
771 				readnull ? '\0' : '\n', listf)) < 0)
772 			break;
773 
774 		if (nlen == 0)
775 			continue;
776 		if (!readnull) {
777 			if (name[nlen-1] == '\n')
778 				name[--nlen] = '\0';
779 			if (nlen == 0)
780 				continue;
781 		}
782 		if (pkglist) {
783 			if (!get_metainfo(name))
784 				continue;
785 			nlen = strlen(name);
786 		}
787 		if (intr)
788 			break;
789 		curfs = NODEV;
790 #ifdef	USE_FIND
791 		if (dofind) {
792 			findcreate(name, state);
793 		} else
794 #endif
795 		create(name, FALSE, FALSE); /* XXX Liste doch wie Kommandozeile? */
796 	}
797 	free(name);
798 }
799 
800 LOCAL BOOL
get_metainfo(line)801 get_metainfo(line)
802 	char	*line;
803 {
804 	char	*p;
805 	char	*p2;
806 	uid_t	uid;
807 	gid_t	gid;
808 	long	lid;
809 
810 	p = strchr(line, ' ');
811 	if (p == NULL) {
812 		statmod = FALSE;
813 		return (TRUE);
814 	}
815 
816 	*p++ = '\0';
817 	statmod = TRUE;
818 	statmode = _BAD_MODE;
819 	statuid = _BAD_UID;
820 	statgid = _BAD_GID;
821 	if (*p == '?') {
822 		p2 = ++p;
823 	} else {
824 		p2 = astolb(p, &lid, 8);
825 		if (*p2 == ' ')
826 			statmode = lid;
827 	}
828 	if (*p2 == ' ') {
829 		p = ++p2;
830 	} else {
831 		errmsgno(EX_BAD, "%s: illegal mode\n", line);
832 		return (FALSE);
833 	}
834 	p2 = strchr(p, ' ');
835 	if (p2 != NULL) {
836 		*p2++ = '\0';
837 	} else {
838 		errmsgno(EX_BAD, "%s: illegal uid\n", line);
839 		return (FALSE);
840 	}
841 	if (!streql(p, "?") && ic_uidname(p, strlen(p), &uid))
842 		statuid = uid;
843 	p = p2;
844 	if (!streql(p, "?") && ic_gidname(p, strlen(p), &gid))
845 		statgid = gid;
846 
847 	return (TRUE);
848 }
849 
850 EXPORT BOOL
read_symlink(sname,name,info,ptb)851 read_symlink(sname, name, info, ptb)
852 	char	*sname;
853 	char	*name;
854 	register FINFO	*info;
855 	TCB	*ptb;
856 {
857 	int	len;
858 
859 	info->f_lname[0] = '\0';
860 
861 #ifdef	HAVE_READLINK
862 	if ((len = lreadlink(sname, info->f_lname, PATH_MAX)) < 0) {
863 		if (!errhidden(E_READLINK, name)) {
864 			if (!errwarnonly(E_READLINK, name))
865 				xstats.s_rwerrs++;
866 			errmsg("Cannot read link '%s'.\n", name);
867 			(void) errabort(E_READLINK, name, TRUE);
868 		}
869 		return (FALSE);
870 	}
871 	info->f_lnamelen = len;
872 	/*
873 	 * string from readlink is not null terminated
874 	 */
875 	info->f_lname[len] = '\0';
876 
877 	if (len > props.pr_maxlnamelen) {
878 		if (!errhidden(E_NAMETOOLONG, name)) {
879 			if (!errwarnonly(E_NAMETOOLONG, name))
880 				xstats.s_toolong++;
881 			errmsgno(EX_BAD,
882 			"%s: Symbolic link too long.\n", name);
883 			(void) errabort(E_NAMETOOLONG, name, TRUE);
884 		}
885 		return (FALSE);
886 	}
887 	if ((props.pr_flags & PR_CPIO) != 0)
888 		return (TRUE);
889 
890 	if (len > props.pr_maxslname) {
891 		if (props.pr_flags & PR_XHDR)
892 			info->f_xflags |= XF_LINKPATH;
893 		else
894 			info->f_flags |= F_LONGLINK;
895 	}
896 	/*
897 	 * if linkname is not longer than props.pr_maxslname
898 	 * that's all to do with linkname
899 	 */
900 	strncpy(ptb->dbuf.t_linkname, info->f_lname, props.pr_maxslname);
901 	return (TRUE);
902 #else
903 	if (!errhidden(E_SPECIALFILE, name)) {
904 		if (!errwarnonly(E_SPECIALFILE, name))
905 			xstats.s_isspecial++;
906 		errmsgno(EX_BAD,
907 		"'%s' unsupported file type '%s'. Not dumped.\n",
908 				name,  XTTONAME(info->f_xftype));
909 		(void) errabort(E_SPECIALFILE, name, TRUE);
910 	}
911 	return (FALSE);
912 #endif
913 }
914 
915 LOCAL LINKS *
find_link(info)916 find_link(info)
917 	register FINFO	*info;
918 {
919 	register LINKS	*lp;
920 
921 	lp = links[l_hash(info)];
922 
923 	for (; lp != (LINKS *)NULL; lp = lp->l_next) {
924 		if (lp->l_ino == info->f_ino && lp->l_dev == info->f_dev)
925 			return (lp);
926 	}
927 	return ((LINKS *)NULL);
928 }
929 
930 /*
931  * Return TRUE in case we found the last entry (the one that may have data)
932  * for a specific file.
933  */
934 EXPORT BOOL
last_cpio_link(info)935 last_cpio_link(info)
936 	register FINFO	*info;
937 {
938 	register LINKS	*lp;
939 
940 	if ((lp = find_link(info)) != NULL) {
941 		if ((!cflag && info->f_size > 0) ||
942 		    lp->l_nlink <= 0 ||
943 		    (lp->l_flags & L_DATA) != 0)
944 			return (TRUE);
945 		return (FALSE);
946 	}
947 	return (TRUE);
948 }
949 
950 /*
951  * Extract all cpio CRC links.
952  * XXX This should be in extract.c
953  */
954 EXPORT BOOL
xcpio_link(info)955 xcpio_link(info)
956 	register FINFO	*info;
957 {
958 	register LINKS	*lp;
959 		char	*name = info->f_name;
960 		char	*lname = info->f_lname;
961 		off_t	rsize = info->f_rsize;
962 		int	xftype = info->f_xftype;
963 
964 	if ((lp = find_link(info)) != NULL) {
965 		/*
966 		 * We come here if the link count increases and we need to
967 		 * archive more "files" as expected.
968 		 */
969 		if ((lp->l_flags & L_DATA) != 0)
970 			return (FALSE);
971 	}
972 	info->f_xftype = info->f_rxftype;
973 	extracti(info, NULL);			/* Extract as real node */
974 	info->f_xftype = xftype;
975 	info->f_rsize = 0;
976 
977 	if (lp != NULL) {
978 		register LNAME	*ln;
979 
980 		lp->l_flags |= L_DATA;
981 		info->f_lname = name;
982 		info->f_name = lp->l_name;
983 		extracti(info, NULL);		/* Extract link info->f_lname */
984 
985 		for (ln = lp->l_lnames; ln; ln = ln->l_lnext) {
986 			if (streql(name, ln->l_lname))
987 				continue;
988 			info->f_name = ln->l_lname;
989 			extracti(info, NULL);	/* Extract all other links */
990 		}
991 	}
992 	info->f_name = name;
993 	info->f_lname = lname;
994 	info->f_rsize = rsize;
995 	return (TRUE);
996 }
997 
998 /*
999  * Archive all cpio CRC links.
1000  *
1001  * We are called if our caller believes that the last link for a specific file
1002  * has been encountered.
1003  */
1004 LOCAL BOOL
acpio_link(info)1005 acpio_link(info)
1006 	register FINFO	*info;
1007 {
1008 		TCB	tb;
1009 	register TCB	*ptb = info->f_tcb;
1010 	register LINKS	*lp;
1011 		int	namelen = info->f_namelen;
1012 		char	*name = info->f_name;
1013 		char	*lname = info->f_lname;
1014 		off_t	size = info->f_size;	/* real size of file	    */
1015 #ifdef	__wrong_but_what_people_would_expect__
1016 		off_t	rsize = info->f_rsize;	/* size as archived on tape */
1017 #endif
1018 
1019 	if ((lp = find_link(info)) != NULL) {
1020 		/*
1021 		 * We come here if the link count increases and we need to
1022 		 * archive more "files" than expected.
1023 		 */
1024 		if ((lp->l_flags & L_DATA) != 0)
1025 			return (FALSE);
1026 	}
1027 
1028 	info->f_size = 0;
1029 	info->f_rsize = 0;
1030 
1031 	if (lp != NULL) {
1032 		register LNAME	*ln;
1033 
1034 		lp->l_flags |= L_DATA;
1035 		info->f_lname = name;
1036 		info->f_namelen = strlen(lp->l_name);
1037 		info->f_name = lp->l_name;
1038 		info_to_tcb(info, ptb);
1039 		put_tcb(ptb, info);
1040 		vprint(info);
1041 
1042 		for (ln = lp->l_lnames; ln; ln = ln->l_lnext) {
1043 			if (streql(name, ln->l_lname))
1044 				continue;
1045 			info->f_namelen = strlen(ln->l_lname);
1046 			info->f_name = ln->l_lname;
1047 			info->f_flags &= ~F_TCB_BUF;
1048 			if ((ptb = (TCB *)get_block(props.pr_hdrsize)) == NULL)
1049 				ptb = &tb;
1050 			else
1051 				info->f_flags |= F_TCB_BUF;
1052 			info->f_tcb = ptb;
1053 			info_to_tcb(info, ptb);
1054 			put_tcb(ptb, info);
1055 			vprint(info);
1056 		}
1057 	}
1058 	info->f_namelen = namelen;
1059 	info->f_name  = name;
1060 	info->f_lname = lname;
1061 	info->f_size  = size;
1062 #ifdef	__wrong_but_what_people_would_expect__
1063 	info->f_rsize = rsize;
1064 #else
1065 	info->f_rsize = size;	/* Achieve that the last link archives data */
1066 #endif
1067 	info->f_xftype = info->f_rxftype;
1068 
1069 	info->f_flags &= ~F_TCB_BUF;
1070 	if ((ptb = (TCB *)get_block(props.pr_hdrsize)) == NULL)
1071 		ptb = &tb;
1072 	else
1073 		info->f_flags |= F_TCB_BUF;
1074 	info->f_tcb = ptb;
1075 	info_to_tcb(info, ptb);
1076 	put_tcb(ptb, info);
1077 	vprint(info);
1078 	return (TRUE);
1079 }
1080 
1081 /*
1082  * Flush all SVr4 cpio -Hcrc links that have not yet been archived.
1083  */
1084 EXPORT void
flushlinks()1085 flushlinks()
1086 {
1087 	register LINKS	*lp;
1088 	register int	i;
1089 
1090 	if ((props.pr_flags & PR_SV_CPIO_LINKS) == 0)
1091 		return;
1092 
1093 	for (i = 0; i < L_HSIZE; i++) {
1094 		if (links[i] == (LINKS *)NULL)
1095 			continue;
1096 
1097 		for (lp = links[i]; lp != (LINKS *)NULL; lp = lp->l_next) {
1098 			if ((lp->l_flags & (L_ISDIR|L_DATA)) == 0 &&
1099 			    (lp->l_nlink > 0))
1100 				flush_link(lp);
1101 		}
1102 	}
1103 }
1104 
1105 /*
1106  * Flush a single cpio -Hcrc link.
1107  */
1108 LOCAL void
flush_link(lp)1109 flush_link(lp)
1110 	register LINKS	*lp;
1111 {
1112 		TCB	tb;
1113 		TCB	*ptb;
1114 		FINFO	finfo;
1115 	register LNAME	*ln;
1116 		int	fd = 1;
1117 		BOOL	did_stat;
1118 		char	*name;
1119 
1120 	finfo.f_flags = 0;
1121 	finfo.f_flags &= ~F_TCB_BUF;
1122 	if ((ptb = (TCB *)get_block(props.pr_hdrsize)) == NULL)
1123 		ptb = &tb;
1124 	else
1125 		finfo.f_flags |= F_TCB_BUF;
1126 	did_stat = getinfo(lp->l_name, &finfo);
1127 	name = lp->l_name;
1128 	for (ln = lp->l_lnames; ln; ln = ln->l_lnext) {
1129 		if (!did_stat) {
1130 			did_stat = getinfo(ln->l_lname, &finfo);
1131 			if (did_stat)
1132 				name = ln->l_lname;
1133 		}
1134 		fd++;
1135 	}
1136 	if (!did_stat) {
1137 		if (!errhidden(E_STAT, lp->l_name)) {
1138 			if (!errwarnonly(E_STAT, lp->l_name))
1139 				xstats.s_staterrs++;
1140 			errmsg("Cannot stat '%s'.\n", lp->l_name);
1141 			(void) errabort(E_STAT, lp->l_name, TRUE);
1142 		}
1143 		return;
1144 	}
1145 	finfo.f_name = lp->l_name;
1146 	finfo.f_namelen = strlen(lp->l_name);
1147 	finfo.f_lname = "";	/* XXX nur �bergangsweise!!!!! */
1148 	finfo.f_lnamelen = 0;
1149 
1150 	finfo.f_nlink = fd;
1151 	finfo.f_xftype = XT_LINK;
1152 	finfo.f_tcb = ptb;
1153 	fd = -1;
1154 	if (is_file(&finfo) && finfo.f_size != 0 && !nullout &&
1155 				(fd = _lfileopen(name, "rb")) < 0) {
1156 		if (!errhidden(E_OPEN, name)) {
1157 			if (!errwarnonly(E_OPEN, name))
1158 				xstats.s_openerrs++;
1159 			errmsg("Cannot open '%s'.\n", name);
1160 			(void) errabort(E_OPEN, name, TRUE);
1161 		}
1162 		return;
1163 	}
1164 	if (acpio_link(&finfo))
1165 		put_file(&fd, &finfo);
1166 
1167 	if (acctime && fd >= 0)
1168 		rs_acctime(fd, &finfo);
1169 	if (fd >= 0)
1170 		close(fd);
1171 }
1172 
1173 /*
1174  * Cheating with st_dev & st_ino for CPIO:
1175  *	Do not use inode number 0 and start st_dev from an
1176  *	obscure value...
1177  */
1178 #define	dev_from_linkno(n)	(0x5555 + ((n) / 0xFFFF))
1179 #define	ino_from_linkno(n)	(1 +	  ((n) % 0xFFFF))
1180 
1181 EXPORT BOOL
read_link(name,namlen,info,ptb)1182 read_link(name, namlen, info, ptb)
1183 	char	*name;
1184 	int	namlen;
1185 	register FINFO	*info;
1186 	TCB	*ptb;
1187 {
1188 	register LINKS	*lp;
1189 	static	Ulong	linkno = 0;
1190 
1191 	if ((lp = find_link(info)) != NULL) {
1192 		if (lp->l_namlen > props.pr_maxlnamelen) {
1193 			if (!errhidden(E_NAMETOOLONG, lp->l_name)) {
1194 				if (!errwarnonly(E_NAMETOOLONG, lp->l_name))
1195 					xstats.s_toolong++;
1196 				errmsgno(EX_BAD,
1197 				"%s: Link name too long.\n",
1198 							lp->l_name);
1199 				(void) errabort(E_NAMETOOLONG, lp->l_name,
1200 								TRUE);
1201 			}
1202 			return (TRUE);
1203 		}
1204 		if (lp->l_namlen > props.pr_maxslname) {
1205 			if (props.pr_flags & PR_XHDR)
1206 				info->f_xflags |= XF_LINKPATH;
1207 			else
1208 				info->f_flags |= F_LONGLINK;
1209 		}
1210 		if (--lp->l_nlink < 0) {
1211 			if (!nowarn && (info->f_flags & F_EXTRACT) == 0)
1212 				errmsgno(EX_BAD,
1213 				"%s: Linkcount below zero (%ld)\n",
1214 					lp->l_name, lp->l_nlink);
1215 		}
1216 		/*
1217 		 * We found a hard link to a directory that is already
1218 		 * known in the link cache. Mark it for later
1219 		 * statistical analysis.
1220 		 */
1221 		if (lp->l_flags & L_ISDIR)
1222 			lp->l_flags |= L_ISLDIR;
1223 		/*
1224 		 * if linkname is not longer than props.pr_maxslname
1225 		 * that's all to do with linkname
1226 		 */
1227 		if ((props.pr_flags & PR_CPIO) == 0) {
1228 			strncpy(ptb->dbuf.t_linkname, lp->l_name,
1229 						props.pr_maxslname);
1230 		}
1231 		info->f_lname = lp->l_name;
1232 		info->f_lnamelen = lp->l_namlen;
1233 		info->f_xftype = XT_LINK;
1234 
1235 		/*
1236 		 * With POSIX-1988, f_rsize is 0 for hardlinks
1237 		 *
1238 		 * XXX Should we add a property for old tar
1239 		 * XXX compatibility to keep the size field as before?
1240 		 */
1241 		if (!linkdata)
1242 			info->f_rsize = (off_t)0;
1243 		/*
1244 		 * XXX This is the wrong place but the TCB has already
1245 		 * XXX been set up (including size field) before.
1246 		 * XXX We only call info_to_tcb() to change size to 0.
1247 		 * XXX There should be a better way to deal with TCB.
1248 		 */
1249 		if ((info->f_flags & F_EXTRACT) == 0) {
1250 			/*
1251 			 * XXX Nicht bei extrakt
1252 			 */
1253 			info->f_dev = dev_from_linkno(lp->l_linkno);
1254 			info->f_ino = ino_from_linkno(lp->l_linkno);
1255 			info_to_tcb(info, ptb);
1256 			info->f_dev = lp->l_dev;
1257 			info->f_ino = lp->l_ino;
1258 		}
1259 		/*
1260 		 * XXX Dies ist eine ungewollte Referenz auf den
1261 		 * XXX TAR Control Block, aber hier ist der TCB
1262 		 * XXX schon fertig und wir wollen nur den Typ
1263 		 * XXX Modifizieren.
1264 		 */
1265 		if ((props.pr_flags & PR_CPIO) == 0)
1266 			ptb->dbuf.t_linkflag = LNKTYPE;
1267 		if ((props.pr_flags & PR_SV_CPIO_LINKS) != 0) {
1268 			register LNAME	*ln;
1269 
1270 			ln = (LNAME *)malloc(sizeof (*ln)+namlen);
1271 			if (ln == NULL) {
1272 				errmsg(
1273 				"Cannot alloc new link name for '%s'.\n",
1274 					name);
1275 			} else {
1276 				strlcpy(ln->l_lname, name, namlen+1);
1277 				ln->l_lnext = lp->l_lnames;
1278 				lp->l_lnames = ln;
1279 			}
1280 		}
1281 		return (TRUE);
1282 	}
1283 	if ((lp = (LINKS *)malloc(sizeof (*lp)+namlen)) == (LINKS *)NULL) {
1284 		errmsg("Cannot alloc new link for '%s'.\n", name);
1285 	} else {
1286 		register LINKS	**lpp = &links[l_hash(info)];
1287 
1288 		lp->l_next = *lpp;
1289 		*lpp = lp;
1290 		lp->l_lnames = NULL;
1291 		lp->l_linkno = linkno++;
1292 		lp->l_ino = info->f_ino;
1293 		lp->l_dev = info->f_dev;
1294 		lp->l_nlink = info->f_nlink - 1;
1295 		lp->l_namlen = namlen;
1296 		if (is_dir(info))
1297 			lp->l_flags = L_ISDIR;
1298 		else
1299 			lp->l_flags = 0;
1300 		strlcpy(lp->l_name, name, namlen+1);
1301 
1302 		if ((info->f_flags & F_EXTRACT) == 0) {
1303 			/*
1304 			 * XXX Nicht bei extrakt
1305 			 */
1306 			info->f_dev = dev_from_linkno(lp->l_linkno);
1307 			info->f_ino = ino_from_linkno(lp->l_linkno);
1308 			info_to_tcb(info, ptb);
1309 			info->f_dev = lp->l_dev;
1310 			info->f_ino = lp->l_ino;
1311 		}
1312 	}
1313 	return (FALSE);
1314 }
1315 
1316 /* ARGSUSED */
1317 LOCAL ssize_t
nullread(vp,cp,amt)1318 nullread(vp, cp, amt)
1319 	void	*vp;
1320 	char	*cp;
1321 	size_t	amt;
1322 {
1323 	return (amt);
1324 }
1325 
1326 EXPORT void
put_file(fp,info)1327 put_file(fp, info)
1328 	register int	*fp;
1329 	register FINFO	*info;
1330 {
1331 	if (nullout) {
1332 		cr_file(info, (ssize_t(*)__PR((void *, char *, size_t)))nullread,
1333 							fp, 0, "reading");
1334 	} else {
1335 		cr_file(info, (ssize_t(*)__PR((void *, char *, size_t)))_fileread,
1336 							fp, 0, "reading");
1337 	}
1338 }
1339 
1340 EXPORT void
cr_file(info,func,arg,amt,text)1341 cr_file(info, func, arg, amt, text)
1342 		FINFO	*info;
1343 		ssize_t	(*func) __PR((void *, char *, size_t));
1344 	register void	*arg;
1345 		long	amt;
1346 		char	*text;
1347 {
1348 	register long	amount;
1349 	register off_t	blocks;
1350 	register off_t	size;
1351 	register int	i = 0;
1352 	register off_t	n;
1353 extern	m_stats	*stats;
1354 
1355 	size = info->f_rsize;
1356 
1357 	fifo_enter_critical();
1358 	stats->cur_size = size;
1359 	stats->cur_off = 0;
1360 	fifo_leave_critical();
1361 
1362 	if ((blocks = tarblocks(info->f_rsize)) == 0)
1363 		return;
1364 	if (amt == 0)
1365 		amt = bufsize;
1366 	do {
1367 		amount = buf_wait(TBLOCK);
1368 		amount = min(amount, amt);
1369 
1370 		if ((props.pr_flags & PR_CPIO) == 0) {
1371 			if ((i = (*func)(arg, bigptr, max(amount, TBLOCK))) <= 0)
1372 				break;
1373 		} else {
1374 			if ((i = (*func)(arg, bigptr, amount)) <= 0)
1375 				break;
1376 		}
1377 
1378 		size -= i;
1379 		fifo_enter_critical();
1380 		stats->cur_off += i;
1381 		fifo_leave_critical();
1382 
1383 		if (size < 0) {			/* File increased in size */
1384 			n = tarblocks(size+i);	/* use expected size only */
1385 		} else {
1386 			n = tarblocks(i);
1387 		}
1388 		if ((props.pr_flags & PR_CPIO) == 0) {
1389 
1390 			if (i % TBLOCK) {	/* Clear (better compression) */
1391 				fillbytes(bigptr+i, TBLOCK - (i%TBLOCK), '\0');
1392 			}
1393 			buf_wake(n*TBLOCK);
1394 		} else {
1395 			if (size < 0)		/* File increased in size */
1396 				buf_wake(size+i); /* use expected size only */
1397 			else
1398 				buf_wake(i);
1399 			n = blocks;
1400 		}
1401 	} while ((blocks -= n) >= 0 && i > 0 && size >= 0);
1402 	if (i < 0) {
1403 		if (!errhidden(E_READ, info->f_name)) {
1404 			if (!errwarnonly(E_READ, info->f_name))
1405 				xstats.s_rwerrs++;
1406 			errmsg("Error %s '%s'.\n", text, info->f_name);
1407 			(void) errabort(E_READ, info->f_name, TRUE);
1408 		}
1409 	} else if ((blocks != 0 || size != 0) && func != nullread) {
1410 		if (!errhidden(size < 0 ? E_GROW:E_SHRINK, info->f_name)) {
1411 			if (!errwarnonly(size < 0 ? E_GROW:E_SHRINK, info->f_name))
1412 				xstats.s_sizeerrs++;
1413 			errmsgno(EX_BAD,
1414 			"'%s': file changed size (%s).\n",
1415 			info->f_name, size < 0 ? "increased":"shrunk");
1416 			(void) errabort(size < 0 ? E_GROW:E_SHRINK,
1417 							info->f_name, TRUE);
1418 		}
1419 	}
1420 	/*
1421 	 * If the file did shrink, fill up to expected size...
1422 	 */
1423 	if ((props.pr_flags & PR_CPIO) == 0) {
1424 		while (--blocks >= 0)
1425 			writeempty();
1426 	} else {
1427 		while (size > 0) {
1428 			amount = buf_wait(1);
1429 			amount = min(amount, size);
1430 			fillbytes(bigptr, amount, '\0');
1431 			buf_wake(amount);
1432 			size -= amount;
1433 		}
1434 	}
1435 	/*
1436 	 * Honour CPIO padding
1437 	 */
1438 	if ((amount = props.pr_pad) != 0) {
1439 		size = info->f_rsize;
1440 		if (info->f_flags & F_LONGNAME)
1441 			size += props.pr_hdrsize;
1442 		amount = (amount + 1 - (size & amount)) & amount;
1443 		while (amount-- > 0) {
1444 			buf_wait(1);
1445 			*bigptr = '\0';
1446 			buf_wake(1);
1447 		}
1448 	}
1449 }
1450 
1451 #define	newfs(i)	((i)->f_dev != curfs)
1452 
1453 LOCAL void
put_dir(sname,dname,namlen,info,ptb,pathp,last)1454 put_dir(sname, dname, namlen, info, ptb, pathp, last)
1455 		char	*sname;
1456 	register char	*dname;
1457 	register int	namlen;
1458 	FINFO	*info;
1459 	TCB	*ptb;
1460 	pathstore_t	*pathp;
1461 	struct pdirs	*last;
1462 {
1463 	static	int	depth	= -10;
1464 	static	int	dinit	= 0;
1465 		FINFO	nfinfo;
1466 	register FINFO	*ninfo	= &nfinfo;
1467 		DIR	*d = NULL;
1468 	struct	dirent	*dir;
1469 #ifdef	HAVE_SEEKDIR
1470 		long	offset	= 0L;
1471 #endif
1472 	pathstore_t	path;
1473 	register char	*name;
1474 		size_t	xlen;
1475 		BOOL	putdir = FALSE;
1476 		BOOL	direrr = FALSE;
1477 		size_t	dlen;
1478 		char	*dp = NULL;
1479 	struct pdirs	thisd;
1480 	struct pdirs	*pd = last;
1481 		BOOL	didslash = FALSE;
1482 
1483 	if (!dinit) {
1484 #ifdef	_SC_OPEN_MAX
1485 		depth += sysconf(_SC_OPEN_MAX);
1486 #else
1487 		depth += getdtablesize();
1488 #endif
1489 		dinit = 1;
1490 	}
1491 
1492 	if (nodump && (info->f_flags & F_NODUMP) != 0)
1493 		return;
1494 
1495 	info->f_dir = NULL;
1496 	info->f_dirinos = NULL;
1497 	info->f_dirlen = 0;
1498 	info->f_dirents = 0;
1499 
1500 	switch (take_file(dname, info)) {
1501 
1502 	case -1:
1503 		if (match_tree)
1504 			return;
1505 		break;
1506 
1507 	case TRUE:
1508 		putdir = TRUE;
1509 	}
1510 
1511 	if ((!nodesc || dodump > 0) && (!nomount || !newfs(info))) {
1512 		/*
1513 		 * If this is a mounted directory and we have been called
1514 		 * with -M, it makes no sense to include the directorie's file
1515 		 * name list with -dump.
1516 		 * By not including this list, we also avoid error messages
1517 		 * like:
1518 		 *	star: Permission denied. Cannot open 'opt/SUNWddk'.
1519 		 *
1520 		 * which is a result of an automounted directory.
1521 		 *
1522 		 * Conclusion: try to use a filesystem snapshot whenever
1523 		 * possible.
1524 		 */
1525 		if (!lowmem) {
1526 			ino_t	*ino = NULL;
1527 			size_t	nents;
1528 
1529 			d = lopendir(sname);
1530 			if (d) {
1531 				dp = dfetchdir(d, sname,
1532 					    &nents, &dlen, dodump?&ino:NULL);
1533 #if	defined(HAVE_FSTATAT) && defined(HAVE_DIRFD)
1534 				if (depth <= 0) {
1535 					closedir(d);
1536 					d = NULL;
1537 				}
1538 #else
1539 				closedir(d);
1540 				d = NULL;
1541 #endif
1542 			} else {
1543 				dp = NULL;
1544 			}
1545 			if (dp == NULL) {
1546 				if (!errhidden(E_OPEN, dname)) {
1547 					if (!errwarnonly(E_OPEN, dname))
1548 						xstats.s_openerrs++;
1549 					errmsg("Cannot open '%s'.\n", dname);
1550 					(void) errabort(E_OPEN, dname, TRUE);
1551 				}
1552 				direrr = TRUE;
1553 			} else {
1554 				info->f_dir = dp;
1555 				info->f_dirinos = ino;
1556 				info->f_dirlen = dlen;
1557 				info->f_dirents = nents;
1558 				/*
1559 				 * Don't count list terminator null Byte
1560 				 */
1561 				dlen--;
1562 			}
1563 		} else if (!(d = lopendir(sname))) {
1564 			if (!errhidden(E_OPEN, dname)) {
1565 				if (!errwarnonly(E_OPEN, dname))
1566 					xstats.s_openerrs++;
1567 				errmsg("Cannot open '%s'.\n", dname);
1568 				(void) errabort(E_OPEN, dname, TRUE);
1569 			}
1570 			direrr = TRUE;
1571 		}
1572 	}
1573 	depth--;
1574 	if (!nodir) {
1575 		if (interactive && !ia_change(ptb, info)) {
1576 			fgtprintf(vpr, "Skipping ...\n");
1577 			if (d)
1578 				closedir(d);
1579 			if (dp)
1580 				free(info->f_dir);
1581 			if (info->f_dirinos)
1582 				free(info->f_dirinos);
1583 			depth++;
1584 			return;
1585 		}
1586 		if (putdir) {
1587 			if (!dirmode)
1588 				put_tcb(ptb, info);
1589 			vprint(info);
1590 		}
1591 	}
1592 	if (direrr) {
1593 		depth++;
1594 		return;
1595 	}
1596 
1597 	/*
1598 	 * Search parent dir structure for possible loops.
1599 	 */
1600 	thisd.p_last = last;
1601 	thisd.p_dev  = info->f_dev;
1602 	thisd.p_ino  = info->f_ino;
1603 
1604 	while (pd) {
1605 		if (pd->p_dev == info->f_dev &&
1606 		    pd->p_ino == info->f_ino) {
1607 			goto out;
1608 		}
1609 		pd = pd->p_last;
1610 	}
1611 
1612 	if (!nodesc && (!nomount || !newfs(info))) {
1613 		if (sname != dname)
1614 			comerrno(EX_BAD, "Panic: put_dir(): sname != dname\n");
1615 
1616 		name = dname;
1617 		if (pathp == NULL) {
1618 			if (name[0] == '.' && name[1] == '/') {
1619 				for (name++; name[0] == '/'; name++)
1620 					/* LINTED */
1621 					;
1622 				namlen -= name - dname;
1623 			}
1624 			if (name[0] == '.' && name[1] == '\0') {
1625 				name++;
1626 				namlen--;
1627 			}
1628 			pathp = &path;
1629 			if (init_pspace(PS_STDERR, pathp) < 0 ||
1630 			    strlcpy_pspace(PS_STDERR, pathp, name, namlen) < 0) {
1631 				toolong("", name, namlen);
1632 				goto out;
1633 			}
1634 		}
1635 		if (namlen && pathp->ps_path[pathp->ps_tail - 1] != '/') {
1636 			char	*p;
1637 
1638 			if ((pathp->ps_tail+2) > pathp->ps_size) {
1639 				if (incr_pspace(PS_STDERR, pathp, 2) < 0) {
1640 					toolong("", name, namlen);
1641 					goto out;
1642 				}
1643 			}
1644 			p = &pathp->ps_path[pathp->ps_tail++];
1645 			*p++ = '/';
1646 			*p++ = '\0';
1647 			namlen++;
1648 			didslash = TRUE;
1649 		}
1650 
1651 		while (!intr) {
1652 			char	*snm;
1653 
1654 			if (lowmem) {
1655 				if ((dir = readdir(d)) == NULL)
1656 					break;
1657 				if (streql(dir->d_name, ".") ||
1658 						streql(dir->d_name, ".."))
1659 					continue;
1660 				snm = dir->d_name;
1661 				xlen = strlen(snm);
1662 			} else {
1663 				if (dlen == 0)
1664 					break;
1665 
1666 				snm = &dp[1];
1667 				xlen = strlen(snm);
1668 				dp += xlen + 2;
1669 				/*
1670 				 * Subtract total element size but make sure
1671 				 * that "dlen" never wraps "below" zero, as it
1672 				 * is unsigned.
1673 				 */
1674 				if ((xlen + 2) > dlen)
1675 					dlen = 0;
1676 				else
1677 					dlen -= xlen + 2;
1678 			}
1679 
1680 			if ((namlen+xlen+1) >= pathp->ps_size) {
1681 				if (grow_pspace(PS_STDERR, pathp, namlen+xlen+1) < 0) {
1682 					toolong(pathp->ps_path, snm, namlen+xlen);
1683 					goto out;
1684 				}
1685 			}
1686 			strcpy(&pathp->ps_path[pathp->ps_tail], snm);
1687 			name = pathp->ps_path;
1688 
1689 #if	defined(HAVE_FSTATAT) && defined(HAVE_DIRFD)
1690 			/*
1691 			 * We get the performance win only with the native
1692 			 * fstatat() and not from the emulation.
1693 			 */
1694 			if (d ? !getinfoat(dirfd(d), snm, ninfo) :
1695 				!getinfo(name, ninfo)) {
1696 #else
1697 			if (!getinfo(name, ninfo)) {
1698 #endif
1699 				if (!errhidden(E_STAT, name)) {
1700 					if (!errwarnonly(E_STAT, name))
1701 						xstats.s_staterrs++;
1702 					errmsg("Cannot stat '%s'.\n", name);
1703 					(void) errabort(E_STAT, name, TRUE);
1704 				}
1705 				continue;
1706 			}
1707 #ifdef	HAVE_SEEKDIR
1708 			if (d && is_dir(ninfo) && depth <= 0) {
1709 				seterrno(0);
1710 				offset = telldir(d);
1711 				if (geterrno()) {
1712 					char	*p;
1713 
1714 					if (pathp->ps_tail == 0) {
1715 						dname = ".";
1716 						p = NULL;
1717 					} else {
1718 						/*
1719 						 * pathstore_t relocates ps_path
1720 						 */
1721 						dname = pathp->ps_path;
1722 						p = &pathp->ps_path[pathp->ps_tail-1];
1723 						*p = '\0';
1724 					}
1725 					if (!errhidden(E_OPEN, dname)) {
1726 						if (!errwarnonly(E_OPEN, dname))
1727 							xstats.s_openerrs++;
1728 						errmsg(
1729 						"WARNING: telldir does not work on '%s'.\n",
1730 						dname);
1731 						(void) errabort(E_OPEN, dname,
1732 									TRUE);
1733 					}
1734 					if (p)
1735 						*p = '/';
1736 					/*
1737 					 * XXX xstats.s_openerrs is wrong here.
1738 					 * Avoid an endless loop on unseekable
1739 					 * directories.
1740 					 */
1741 					/* closedir() is past end of loop */
1742 					break;
1743 				}
1744 				closedir(d);
1745 			}
1746 #endif
1747 			pathp->ps_tail += xlen;
1748 			createi(name, name, xlen+namlen, ninfo, pathp, &thisd);
1749 			pathp->ps_tail -= xlen;
1750 			pathp->ps_path[pathp->ps_tail] = '\0';
1751 #ifdef	HAVE_SEEKDIR
1752 			if (d && is_dir(ninfo) && depth <= 0) {
1753 				char	*p;
1754 
1755 				if (pathp->ps_tail == 0) {
1756 					sname = dname = ".";
1757 					p = NULL;
1758 				} else {
1759 					/*
1760 					 * pathstore_t relocates ps_path
1761 					 */
1762 					sname = dname = pathp->ps_path;
1763 					p = &pathp->ps_path[pathp->ps_tail-1];
1764 					*p = '\0';
1765 				}
1766 				if (!(d = lopendir(sname))) {
1767 					if (!errhidden(E_OPEN, dname)) {
1768 						if (!errwarnonly(E_OPEN, dname))
1769 							xstats.s_openerrs++;
1770 						errmsg("Cannot open '%s'.\n",
1771 							dname);
1772 						(void) errabort(E_OPEN, dname,
1773 									TRUE);
1774 					}
1775 					if (p)
1776 						*p = '/';
1777 					break;
1778 				}
1779 				seterrno(0);
1780 				seekdir(d, offset);
1781 				if (geterrno()) {
1782 					if (!errhidden(E_OPEN, dname)) {
1783 						if (!errwarnonly(E_OPEN, dname))
1784 							xstats.s_openerrs++;
1785 						errmsg(
1786 						"WARNING: seekdir does not work on '%s'.\n",
1787 						dname);
1788 						(void) errabort(E_OPEN, dname,
1789 									TRUE);
1790 					}
1791 					/*
1792 					 * XXX xstats.s_openerrs is wrong here.
1793 					 * Avoid an endless loop on unseekable
1794 					 * directories.
1795 					 */
1796 					if (p)
1797 						*p = '/';
1798 					break;
1799 				}
1800 				if (p)
1801 					*p = '/';
1802 			}
1803 #endif
1804 		}
1805 	}
1806 out:
1807 	if (didslash)
1808 		pathp->ps_path[--pathp->ps_tail] = '\0';
1809 	if (d)
1810 		closedir(d);
1811 	if (dp)
1812 		free(info->f_dir);
1813 	if (info->f_dirinos)
1814 		free(info->f_dirinos);
1815 	if (pathp == &path)
1816 		free_pspace(pathp);
1817 	depth++;
1818 	if (!nodir && dirmode && putdir)
1819 		put_tcb(ptb, info);
1820 }
1821 
1822 /*
1823  * This is currently only called in case we did run out of memory.
1824  */
1825 LOCAL void
toolong(dname,name,len)1826 toolong(dname, name, len)
1827 	char	*dname;
1828 	char	*name;
1829 	size_t	len;
1830 {
1831 	if (!errhidden(E_NAMETOOLONG, name)) {
1832 		if (!errwarnonly(E_NAMETOOLONG, name))
1833 			xstats.s_toolong++;
1834 		errmsgno(EX_BAD, "%s%s: Name too long (%lu), out of memory.\n",
1835 			dname, name,
1836 			(unsigned long)len);
1837 		(void) errabort(E_NAMETOOLONG, name, TRUE);
1838 	}
1839 }
1840 
1841 LOCAL BOOL
checkdirexclude(sname,name,namlen,info)1842 checkdirexclude(sname, name, namlen, info)
1843 	char	*sname;
1844 	char	*name;
1845 	int	namlen;
1846 	FINFO	*info;
1847 {
1848 	FINFO	finfo;
1849 	char	pname[PATH_MAX+1];
1850 	char	*pnamep = pname;
1851 	size_t	pnamelen = sizeof (pname);
1852 	size_t	pnlen;
1853 	int	OFflag = Fflag;
1854 	char	*p;
1855 	BOOL	ret = TRUE;
1856 
1857 	Fflag = 0;
1858 	pnlen = namlen;
1859 	pnlen += 2 + 8;		/* Null Byte + '/' + strlen(".exclude") */
1860 	if (pnlen > pnamelen) {
1861 		pnamep = __fjmalloc(stderr, pnlen, "name buffer", JM_RETURN);
1862 		if (pnamep == NULL) {
1863 			errmsg("Cannot check '%s' for exclude\n", name);
1864 			goto notfound;
1865 		}
1866 	}
1867 	strcpy(pnamep, name);
1868 	p = &pnamep[namlen];
1869 	if (p[-1] != '/') {
1870 		*p++ = '/';
1871 	}
1872 	strcpy(p, ".mirror");
1873 	if (!_getinfo(pnamep, &finfo)) {
1874 		strcpy(p, ".exclude");
1875 		if (!_getinfo(pnamep, &finfo))
1876 			goto notfound;
1877 	}
1878 	if (is_file(&finfo)) {
1879 		if (OFflag == 3) {
1880 			nodesc++;
1881 			if (!dirmode) {
1882 				createi(sname, name, namlen, info,
1883 					(pathstore_t *)0,
1884 					(struct pdirs *)0);
1885 			}
1886 			create(pnamep, FALSE, FALSE);	/* Needed to strip off "./" */
1887 			if (dirmode) {
1888 				createi(sname, name, namlen, info,
1889 					(pathstore_t *)0,
1890 					(struct pdirs *)0);
1891 			}
1892 			nodesc--;
1893 		}
1894 		ret = FALSE;
1895 	}
1896 notfound:
1897 	if (pnamep != pname)
1898 		free(pnamep);
1899 	Fflag = OFflag;
1900 	return (ret);
1901 }
1902 
1903 LOCAL BOOL
checkexclude(sname,name,namlen,info)1904 checkexclude(sname, name, namlen, info)
1905 	char	*sname;
1906 	char	*name;
1907 	int	namlen;
1908 	FINFO	*info;
1909 {
1910 		int	len;
1911 	const	char	*fn;
1912 
1913 	if (Fflag <= 0)
1914 		return (TRUE);
1915 
1916 	fn = filename(name);
1917 
1918 	if (is_dir(info)) {
1919 		/*
1920 		 * Exclude with -F -FF -FFFFF 1, 2, 5+
1921 		 */
1922 		if (Fflag < 3 || Fflag > 4) {
1923 			if (streql(fn, "SCCS") ||	/* SCCS directory */
1924 			    streql(fn, "RCS"))		/* RCS directory  */
1925 				return (FALSE);
1926 		}
1927 		if (Fflag > 1 && streql(fn, "OBJ"))	/* OBJ directory  */
1928 			return (FALSE);
1929 		if (Fflag > 2 && !checkdirexclude(sname, name, namlen, info))
1930 			return (FALSE);
1931 		return (TRUE);
1932 	}
1933 	if ((len = strlen(fn)) < 3)		/* Will never match later */
1934 		return (TRUE);
1935 
1936 	if (Fflag > 1 && fn[len-2] == '.' && fn[len-1] == 'o')	/* obj files */
1937 		return (FALSE);
1938 
1939 	if (Fflag > 1 && is_file(info)) {
1940 		if (streql(fn, "core") ||
1941 		    streql(fn, "errs") ||
1942 		    streql(fn, "a.out"))
1943 			return (FALSE);
1944 	}
1945 
1946 	return (TRUE);
1947 }
1948 
1949 #ifdef	USE_FIND
1950 /*
1951  * The callback function for treewalk()
1952  *
1953  * XXX errhidden() support not yet implemented.
1954  */
1955 EXPORT int
walkfunc(nm,fs,type,state)1956 walkfunc(nm, fs, type, state)
1957 	char		*nm;
1958 	struct stat	*fs;
1959 	int		type;
1960 	struct WALK	*state;
1961 {
1962 	if (intr) {
1963 		state->flags |= WALK_WF_QUIT;
1964 		return (0);
1965 	}
1966 	if (type == WALK_NS) {
1967 		errmsg("Cannot stat '%s'.\n", nm);
1968 		state->err = 1;
1969 		return (0);
1970 	} else if (type == WALK_SLN && (state->walkflags & WALK_PHYS) == 0) {
1971 		errmsg("Cannot follow symlink '%s'.\n", nm);
1972 		state->err = 1;
1973 		return (0);
1974 	} else if (type == WALK_DNR) {
1975 		if (state->flags & WALK_WF_NOCHDIR)
1976 			errmsg("Cannot chdir to '%s'.\n", nm);
1977 		else
1978 			errmsg("Cannot read '%s'.\n", nm);
1979 		state->err = 1;
1980 		return (0);
1981 	}
1982 	if (state->maxdepth >= 0 && state->level >= state->maxdepth)
1983 		state->flags |= WALK_WF_PRUNE;
1984 	if (state->mindepth >= 0 && state->level < state->mindepth)
1985 		return (0);
1986 
1987 	if (state->tree == NULL ||
1988 	    find_expr(nm, nm + state->base, fs, state, state->tree)) {
1989 		FINFO	finfo;
1990 		extern char	*listfile;
1991 
1992 		finfo.f_sname = nm + state->base;
1993 		finfo.f_name = nm;
1994 		stat_to_info(AT_FDCWD, fs, &finfo);
1995 		if (nomount && newfs(&finfo))
1996 			return (0);
1997 		if (listfile)		/* We did not do a chdir() */
1998 			state->base = 0;
1999 		createi(nm + state->base, nm, strlen(nm), &finfo,
2000 			(pathstore_t *)0, (struct pdirs *)0);
2001 	}
2002 	return (0);
2003 }
2004 
2005 LOCAL void
findcreate(name,state)2006 findcreate(name, state)
2007 	register char	*name;
2008 	struct WALK	*state;
2009 {
2010 	struct stat	statbuf;
2011 	int		type = WALK_NONE;
2012 
2013 	if (!getstat(name, &statbuf)) {
2014 		if (!errhidden(E_STAT, name)) {
2015 			if (!errwarnonly(E_STAT, name))
2016 				xstats.s_staterrs++;
2017 			errmsg("Cannot stat '%s'.\n", name);
2018 			(void) errabort(E_STAT, name, TRUE);
2019 		}
2020 		return;
2021 	}
2022 
2023 	walksname(name, state);
2024 	(void) walkfunc(name, &statbuf, type, state);
2025 }
2026 #endif
2027