da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/***********************************************************************
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* This software is part of the ast package *
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner* Copyright (c) 1985-2010 AT&T Intellectual Property *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* and is licensed under the *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Common Public License, Version 1.0 *
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin* by AT&T Intellectual Property *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* A copy of the License is available at *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* http://www.opensource.org/licenses/cpl1.0.txt *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Information and Software Systems Research *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* AT&T Research *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Florham Park NJ *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Glenn Fowler <gsf@research.att.com> *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* David Korn <dgk@research.att.com> *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Phong Vo <kpv@research.att.com> *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin***********************************************************************/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#pragma prototyped
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Phong Vo
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Glenn Fowler
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * AT&T Research
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * fts implementation unwound from the kpv ftwalk() of 1988-10-30
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include <ast.h>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include <ast_dir.h>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include <error.h>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include <fs3d.h>
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#include <ls.h>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstruct Ftsent;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chintypedef int (*Compar_f)(struct Ftsent* const*, struct Ftsent* const*);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chintypedef int (*Stat_f)(const char*, struct stat*);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz#define _fts_status status
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz#define _fts_statb statb
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define _FTS_PRIVATE_ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin FTSENT* parent; /* top parent */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin FTSENT* todo; /* todo list */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin FTSENT* top; /* top element */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin FTSENT* root; \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin FTSENT* bot; /* bottom element */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin FTSENT* free; /* free element */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin FTSENT* diroot; \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin FTSENT* curdir; \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin FTSENT* current; /* current element */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin FTSENT* previous; /* previous current */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin FTSENT* dotdot; \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin FTSENT* link; /* real current fts_link*/ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin FTSENT* pwd; /* pwd parent */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin DIR* dir; /* current dir stream */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Compar_f comparf; /* node comparison func */ \
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz size_t baselen; /* current strlen(base) */ \
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz size_t homesize; /* sizeof(home) */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int cd; /* chdir status */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int cpname; \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int flags; /* fts_open() flags */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int nd; \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unsigned char children; \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unsigned char fs3d; \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unsigned char nostat; \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unsigned char state; /* fts_read() state */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char* base; /* basename in path */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char* name; \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char* path; /* path workspace */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char* home; /* home/path buffer */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char* endbase; /* space to build paths */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char* endbuf; /* space to build paths */ \
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin char* pad[2]; /* $0.02 to splain this */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * NOTE: <ftwalk.h> relies on status and statb being the first two elements
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define _FTSENT_PRIVATE_ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int nd; /* popdir() count */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin FTSENT* left; /* left child */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin FTSENT* right; /* right child */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin FTSENT* pwd; /* pwd parent */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin FTSENT* stack; /* getlist() stack */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin long nlink; /* FTS_D link count */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unsigned char must; /* must stat */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unsigned char type; /* DT_* type */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unsigned char symlink; /* originally a symlink */ \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char name[sizeof(int)]; /* fts_name data */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include <fts.h>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifndef ENOSYS
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define ENOSYS EINVAL
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if MAXNAMLEN > 16
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define MINNAME 32
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define MINNAME 16
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define drop(p,f) (((f)->fts_namelen < MINNAME) ? ((f)->fts_link = (p)->free, (p)->free = (f)) : (free(f), (p)->free))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define ACCESS(p,f) ((p)->cd==0?(f)->fts_name:(f)->fts_path)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define PATH(f,p,l) ((!((f)->flags&FTS_SEEDOTDIR)&&(l)>0&&(p)[0]=='.'&&(p)[1]=='/')?((p)+2):(p))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define SAME(one,two) ((one)->st_ino==(two)->st_ino&&(one)->st_dev==(two)->st_dev)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define SKIPLINK(p,f) ((f)->fts_parent->nlink == 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifdef D_TYPE
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define ISTYPE(f,t) ((f)->type == (t))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define TYPE(f,t) ((f)->type = (t))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define SKIP(p,f) ((f)->fts_parent->must == 0 && (((f)->type == DT_UNKNOWN) ? SKIPLINK(p,f) : ((f)->type != DT_DIR && ((f)->type != DT_LNK || ((p)->flags & FTS_PHYSICAL)))))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#undef DT_UNKNOWN
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define DT_UNKNOWN 0
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#undef DT_LNK
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define DT_LNK 1
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define ISTYPE(f,t) ((t)==DT_UNKNOWN)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define TYPE(f,d)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define SKIP(p,f) ((f)->fts_parent->must == 0 && SKIPLINK(p,f))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifndef D_FILENO
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define D_FILENO(d) (1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * NOTE: a malicious dir rename() could change .. underfoot so we
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * must always verify; undef verify to enable the unsafe code
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define verify 1
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * FTS_NOSTAT requires a dir with
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * D_TYPE(&dirent_t)!=DT_UNKNOWN
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * OR
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * st_nlink>=2
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define FTS_children_resume 1
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define FTS_children_return 2
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define FTS_error 3
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define FTS_popstack 4
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define FTS_popstack_resume 5
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define FTS_popstack_return 6
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define FTS_preorder 7
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define FTS_preorder_resume 8
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define FTS_preorder_return 9
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define FTS_readdir 10
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define FTS_terminal 11
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define FTS_todo 12
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define FTS_top_return 13
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chintypedef int (*Notify_f)(FTS*, FTSENT*, void*);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chintypedef struct Notify_s
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct Notify_s* next;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Notify_f notifyf;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin void* context;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin} Notify_t;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic Notify_t* notify;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * allocate an FTSENT node
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic FTSENT*
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainznode(FTS* fts, FTSENT* parent, register char* name, register size_t namelen)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register FTSENT* f;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz register size_t n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (fts->free && namelen < MINNAME)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin f = fts->free;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fts->free = f->fts_link;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = (namelen < MINNAME ? MINNAME : namelen + 1) - sizeof(int);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(f = newof(0, FTSENT, 1, n)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fts->fts_errno = errno;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fts->state = FTS_error;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin f->fts = fts;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin TYPE(f, DT_UNKNOWN);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin f->status = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin f->symlink = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin f->fts_level = (f->fts_parent = parent)->fts_level + 1;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz#if __OBSOLETE__ < 20140101
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz f->_fts_level = (short)f->fts_level;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin f->fts_link = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin f->fts_pointer = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin f->fts_number = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin f->fts_errno = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin f->fts_namelen = namelen;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz#if __OBSOLETE__ < 20140101
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz f->_fts_namelen = (unsigned short)f->fts_namelen;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin f->fts_name = f->name;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin f->fts_statp = &f->statb;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin memcpy(f->fts_name, name, namelen + 1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return f;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * compare directories by device/inode
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatcmp(FTSENT* const* pf1, FTSENT* const* pf2)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register const FTSENT* f1 = *pf1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register const FTSENT* f2 = *pf2;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (f1->statb.st_ino < f2->statb.st_ino)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (f1->statb.st_ino > f2->statb.st_ino)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (f1->statb.st_dev < f2->statb.st_dev)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (f1->statb.st_dev > f2->statb.st_dev)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * hack for NFS where <dev,ino> may not uniquely identify objects
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (f1->statb.st_mtime < f2->statb.st_mtime)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (f1->statb.st_mtime > f2->statb.st_mtime)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * search trees with top-down splaying (a la Tarjan and Sleator)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * when used for insertion sort, this implements a stable sort
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define RROTATE(r) (t = r->left, r->left = t->right, t->right = r, r = t)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define LROTATE(r) (t = r->right, r->right = t->left, t->left = r, r = t)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic FTSENT*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinsearch(FTSENT* e, FTSENT* root, int(*comparf)(FTSENT* const*, FTSENT* const*), int insert)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int cmp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register FTSENT* t;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register FTSENT* left;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register FTSENT* right;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register FTSENT* lroot;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register FTSENT* rroot;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin left = right = lroot = rroot = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (root)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(cmp = (*comparf)(&e, &root)) && !insert)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (cmp < 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * this is the left zig-zig case
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (root->left && (cmp = (*comparf)(&e, &root->left)) <= 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin RROTATE(root);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!cmp && !insert)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * stick all things > e to the right tree
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (right)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin right->left = root;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin rroot = root;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin right = root;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin root = root->left;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin right->left = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * this is the right zig-zig case
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (root->right && (cmp = (*comparf)(&e, &root->right)) >= 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin LROTATE(root);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!cmp && !insert)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * stick all things <= e to the left tree
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (left)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin left->right = root;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin lroot = root;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin left = root;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin root = root->right;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin left->right = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!root)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin root = e;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (right)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin right->left = root->right;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin rroot = root->right;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (left)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin left->right = root->left;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin lroot = root->left;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin root->left = lroot;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin root->right = rroot;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return root;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * delete the root element from the tree
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic FTSENT*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chindeleteroot(register FTSENT* root)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register FTSENT* t;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register FTSENT* left;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register FTSENT* right;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin right = root->right;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(left = root->left))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin root = right;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (left->right)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin LROTATE(left);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin left->right = right;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin root = left;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return root;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * generate ordered fts_link list from binary tree at root
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * FTSENT.stack instead of recursion to avoid blowing the real
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * stack on big directories
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic void
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chingetlist(register FTSENT** top, register FTSENT** bot, register FTSENT* root)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register FTSENT* stack = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (;;)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (root->left)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin root->stack = stack;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stack = root;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin root = root->left;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (;;)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*top)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *bot = (*bot)->fts_link = root;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *bot = *top = root;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (root->right)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin root = root->right;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(root = stack))
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz (*bot)->fts_link = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stack = stack->stack;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * set directory when curdir is lost in space
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinsetdir(register char* home, register char* path)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int cdrv;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (path[0] == '/')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cdrv = pathcd(path, NiL);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * note that path and home are in the same buffer
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin path[-1] = '/';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cdrv = pathcd(home, NiL);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin path[-1] = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (cdrv < 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pathcd(home, NiL);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return cdrv;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * set to parent dir
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinsetpdir(register char* home, register char* path, register char* base)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int cdrv;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (base > path)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = base[0];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin base[0] = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cdrv = setdir(home, path);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin base[0] = c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cdrv = pathcd(home, NiL);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return cdrv;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * pop a set of directories
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinpopdirs(FTS* fts)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register FTSENT*f;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char* s;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char* e;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifndef verify
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int verify;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct stat sb;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char buf[PATH_MAX];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(f = fts->curdir) || f->fts_level < 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin e = buf + sizeof(buf) - 4;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifndef verify
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin verify = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (fts->nd > 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (s = buf; s < e && fts->nd > 0; fts->nd--)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (fts->pwd)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifndef verify
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin verify |= fts->pwd->symlink;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fts->pwd = fts->pwd->pwd;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *s++ = '.';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *s++ = '.';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *s++ = '/';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *s = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (chdir(buf))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return (verify && (stat(".", &sb) < 0 || !SAME(&sb, f->fts_statp))) ? -1 : 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * initialize st from path and fts_info from st
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chininfo(FTS* fts, register FTSENT* f, const char* path, struct stat* sp, int flags)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (path)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifdef S_ISLNK
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!f->symlink && (ISTYPE(f, DT_UNKNOWN) || ISTYPE(f, DT_LNK)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (lstat(path, sp) < 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto bad;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (stat(path, sp) < 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto bad;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifdef S_ISLNK
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin again:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (S_ISDIR(sp->st_mode))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((flags & FTS_NOSTAT) && !fts->fs3d)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin f->fts_parent->nlink--;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifdef D_TYPE
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((f->nlink = sp->st_nlink) < 2)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin f->must = 2;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin f->nlink = 2;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin f->must = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((f->nlink = sp->st_nlink) >= 2)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin f->must = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin f->must = 2;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin f->must = 2;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin TYPE(f, DT_DIR);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin f->fts_info = FTS_D;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifdef S_ISLNK
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (S_ISLNK((sp)->st_mode))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct stat sb;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin f->symlink = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(flags & FTS_PHYSICAL) && stat(path, &sb) >= 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *sp = sb;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin flags = FTS_PHYSICAL;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto again;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin TYPE(f, DT_LNK);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin f->fts_info = FTS_SL;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin TYPE(f, DT_REG);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin f->fts_info = FTS_F;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin bad:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin TYPE(f, DT_UNKNOWN);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin f->fts_info = FTS_NS;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * get top list of elements to process
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz * ordering delayed until first fts_read()
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz * to give caller a chance to set fts->handle
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic FTSENT*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chintoplist(FTS* fts, register char* const* pathnames)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char* path;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register FTSENT* f;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz register FTSENT* top;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz register FTSENT* bot;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int physical;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int metaphysical;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char* s;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct stat st;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (fts->flags & FTS_NOSEEDOTDIR)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fts->flags &= ~FTS_SEEDOTDIR;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin physical = (fts->flags & FTS_PHYSICAL);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin metaphysical = (fts->flags & (FTS_META|FTS_PHYSICAL)) == (FTS_META|FTS_PHYSICAL);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz top = bot = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (path = *pathnames++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * make elements
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(f = node(fts, fts->parent, path, strlen(path))))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin path = f->fts_name;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!physical)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin f->fts_namelen = (fts->flags & FTS_SEEDOTDIR) ? strlen(path) : (pathcanon(path, 0) - path);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (*path != '.')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin f->fts_namelen = strlen(path);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fts->flags |= FTS_SEEDOTDIR;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (fts->flags & FTS_NOSEEDOTDIR)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fts->flags &= ~FTS_SEEDOTDIR;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s = path;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (*s++ == '.' && *s++ == '/')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (*s == '/')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!*s)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin path = f->fts_name;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (*path++ = *s++);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin path = f->fts_name;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fts->flags |= FTS_SEEDOTDIR;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (s = path + strlen(path); s > path && *(s - 1) == '/'; s--);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *s = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin f->fts_namelen = s - path;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz#if __OBSOLETE__ < 20140101
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz f->_fts_namelen = (unsigned short)f->fts_namelen;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!*path)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errno = ENOENT;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin f->fts_info = FTS_NS;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz info(fts, f, path, f->fts_statp, fts->flags);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifdef S_ISLNK
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * don't let any standards committee get
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * away with calling your idea a hack
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (metaphysical && f->fts_info == FTS_SL && stat(path, &st) >= 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz *f->fts_statp = st;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz info(fts, f, NiL, f->fts_statp, 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (bot)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin bot->fts_link = f;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin bot = f;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin top = bot = f;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return top;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz/*
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz * order fts->todo if fts->comparf != 0
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz */
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainzstatic void
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainzorder(FTS* fts)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz{
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz register FTSENT* f;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz register FTSENT* root;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz FTSENT* top;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz FTSENT* bot;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz top = bot = root = 0;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz for (f = fts->todo; f; f = f->fts_link)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz root = search(f, root, fts->comparf, 1);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz getlist(&top, &bot, root);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz fts->todo = top;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz}
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * resize the path buffer
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * note that free() is not used because we may need to chdir(fts->home)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * if there isn't enough space to continue
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainzresize(register FTS* fts, size_t inc)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char* old;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char* newp;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz register size_t n_old;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * add space for "/." used in testing FTS_DNX
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n_old = fts->homesize;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fts->homesize = ((fts->homesize + inc + 4) / PATH_MAX + 1) * PATH_MAX;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(newp = newof(0, char, fts->homesize, 0)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fts->fts_errno = errno;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fts->state = FTS_error;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin old = fts->home;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fts->home = newp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin memcpy(newp, old, n_old);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (fts->endbuf)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fts->endbuf = newp + fts->homesize - 4;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (fts->path)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fts->path = newp + (fts->path - old);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (fts->base)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fts->base = newp + (fts->base - old);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin free(old);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * open a new fts stream on pathnames
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinFTS*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinfts_open(char* const* pathnames, int flags, int (*comparf)(FTSENT* const*, FTSENT* const*))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register FTS* fts;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(fts = newof(0, FTS, 1, sizeof(FTSENT))))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fts->flags = flags;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fts->cd = (flags & FTS_NOCHDIR) ? 1 : -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fts->comparf = comparf;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fts->fs3d = fs3d(FS3D_TEST);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * set up the path work buffer
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fts->homesize = 2 * PATH_MAX;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (;;)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(fts->home = newof(fts->home, char, fts->homesize, 0)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin free(fts);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (fts->cd > 0 || getcwd(fts->home, fts->homesize))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (errno == ERANGE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fts->homesize += PATH_MAX;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fts->cd = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fts->endbuf = fts->home + fts->homesize - 4;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * initialize the tippity-top
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fts->parent = (FTSENT*)(fts + 1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fts->parent->fts_info = FTS_D;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin memcpy(fts->parent->fts_accpath = fts->parent->fts_path = fts->parent->fts_name = fts->parent->name, ".", 2);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fts->parent->fts_level = -1;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz#if __OBSOLETE__ < 20140101
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz fts->parent->_fts_level = (short)fts->parent->fts_level;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fts->parent->fts_statp = &fts->parent->statb;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fts->parent->must = 2;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fts->parent->type = DT_UNKNOWN;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fts->path = fts->home + strlen(fts->home) + 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * make the list of top elements
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!pathnames || (flags & FTS_ONEPATH) || !*pathnames)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char* v[2];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin v[0] = pathnames && (flags & FTS_ONEPATH) ? (char*)pathnames : ".";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin v[1] = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fts->todo = toplist(fts, v);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fts->todo = toplist(fts, pathnames);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!fts->todo || fts->todo->fts_info == FTS_NS && !fts->todo->fts_link)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fts_close(fts);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return fts;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * return the next FTS entry
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinFTSENT*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinfts_read(register FTS* fts)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char* s;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register FTSENT* f;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct dirent* d;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz size_t i;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin FTSENT* t;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Notify_t* p;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifdef verify
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct stat sb;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz for (;;)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz switch (fts->state)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz case FTS_top_return:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz f = fts->todo;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz t = 0;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz while (f)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (f->status == FTS_SKIP)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (t)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz t->fts_link = f->fts_link;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz drop(fts, f);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz f = t->fts_link;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz else
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz fts->todo = f->fts_link;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz drop(fts, f);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz f = fts->todo;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz t = f;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz f = f->fts_link;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz /*FALLTHROUGH*/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz case 0:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (!fts->state && fts->comparf)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz order(fts);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (!(f = fts->todo))
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz return 0;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz /*FALLTHROUGH*/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz case FTS_todo:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz /*
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz * process the top object on the stack
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz fts->root = fts->top = fts->bot = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz /*
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz * initialize the top level
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (f->fts_level == 0)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz fts->parent->fts_number = f->fts_number;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz fts->parent->fts_pointer = f->fts_pointer;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz fts->parent->fts_statp = f->fts_statp;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz fts->parent->statb = *f->fts_statp;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz f->fts_parent = fts->parent;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz fts->diroot = 0;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (fts->cd == 0)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz pathcd(fts->home, NiL);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz else if (fts->cd < 0)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz fts->cd = 0;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz fts->pwd = f->fts_parent;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz fts->curdir = fts->cd ? 0 : f->fts_parent;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz *(fts->base = fts->path) = 0;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz /*
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz * chdir to parent if asked for
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (fts->cd < 0)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz fts->cd = setdir(fts->home, fts->path);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz fts->pwd = f->fts_parent;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz fts->curdir = fts->cd ? 0 : f->fts_parent;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz /*
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz * add object's name to the path
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if ((fts->baselen = f->fts_namelen) >= (fts->endbuf - fts->base) && resize(fts, fts->baselen))
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz return 0;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz memcpy(fts->base, f->name, fts->baselen + 1);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz fts->name = fts->cd ? fts->path : fts->base;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz /*FALLTHROUGH*/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz case FTS_preorder:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz /*
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz * check for cycle and open dir
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (f->fts_info == FTS_D)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if ((fts->diroot = search(f, fts->diroot, statcmp, 0)) != f || f->fts_level > 0 && (t = f) && statcmp(&t, &f->fts_parent) == 0)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz f->fts_info = FTS_DC;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz f->fts_cycle = fts->diroot;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz else if (!(fts->flags & FTS_TOP) && (!(fts->flags & FTS_XDEV) || f->statb.st_dev == f->fts_parent->statb.st_dev))
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz /*
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz * buffer is known to be large enough here!
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz */
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (fts->base[fts->baselen - 1] != '/')
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz memcpy(fts->base + fts->baselen, "/.", 3);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (!(fts->dir = opendir(fts->name)))
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz f->fts_info = FTS_DNX;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz fts->base[fts->baselen] = 0;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (!fts->dir && !(fts->dir = opendir(fts->name)))
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz f->fts_info = FTS_DNR;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz f->nd = f->fts_info & ~FTS_DNX;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (f->nd || !(fts->flags & FTS_NOPREORDER))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz fts->current = f;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz fts->link = f->fts_link;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz f->fts_link = 0;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz f->fts_path = PATH(fts, fts->path, f->fts_level);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz f->fts_pathlen = (fts->base - f->fts_path) + fts->baselen;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz f->fts_accpath = ACCESS(fts, f);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz fts->state = FTS_preorder_return;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz goto note;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz /*FALLTHROUGH*/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz case FTS_preorder_resume:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz /*
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz * prune
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (!fts->dir || f->nd || f->status == FTS_SKIP)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (fts->dir)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz closedir(fts->dir);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz fts->dir = 0;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz fts->state = FTS_popstack;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz /*
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz * FTS_D or FTS_DNX, about to read children
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (fts->cd == 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if ((fts->cd = chdir(fts->name)) < 0)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz pathcd(fts->home, NiL);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz else if (fts->pwd != f)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz f->pwd = fts->pwd;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz fts->pwd = f;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz fts->curdir = fts->cd < 0 ? 0 : f;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz fts->nostat = fts->children > 1 || f->fts_info == FTS_DNX;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz fts->cpname = fts->cd && !fts->nostat || !fts->children && !fts->comparf;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz fts->dotdot = 0;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz fts->endbase = fts->base + fts->baselen;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (fts->endbase[-1] != '/')
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz *fts->endbase++ = '/';
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz fts->current = f;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz /*FALLTHROUGH*/
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz case FTS_readdir:
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz while (d = readdir(fts->dir))
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz s = d->d_name;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (s[0] == '.')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (s[1] == 0)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz fts->current->nlink--;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (!(fts->flags & FTS_SEEDOT))
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz continue;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz n = 1;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz else if (s[1] == '.' && s[2] == 0)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz fts->current->nlink--;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (fts->current->must == 1)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz fts->current->must = 0;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (!(fts->flags & FTS_SEEDOT))
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz continue;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz n = 2;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz else
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz n = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz /*
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz * make a new entry
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz i = D_NAMLEN(d);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (!(f = node(fts, fts->current, s, i)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz TYPE(f, D_TYPE(d));
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz * check for space
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (i >= fts->endbuf - fts->endbase)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (resize(fts, i))
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz return 0;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz fts->endbase = fts->base + fts->baselen;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (fts->endbase[-1] != '/')
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz fts->endbase++;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (fts->cpname)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz memcpy(fts->endbase, s, i + 1);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (fts->cd)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz s = fts->path;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (n)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz /*
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz * don't recurse on . and ..
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz */
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (n == 1)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz f->fts_statp = fts->current->fts_statp;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (f->fts_info != FTS_NS)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz fts->dotdot = f;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (fts->current->fts_parent->fts_level < 0)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz f->fts_statp = &fts->current->fts_parent->statb;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz info(fts, f, s, f->fts_statp, 0);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz else
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz f->fts_statp = fts->current->fts_parent->fts_statp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz f->fts_info = FTS_DOT;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz else if ((fts->nostat || SKIP(fts, f)) && (f->fts_info = FTS_NSOK) || info(fts, f, s, &f->statb, fts->flags))
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz f->statb.st_ino = D_FILENO(d);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (fts->comparf)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz fts->root = search(f, fts->root, fts->comparf, 1);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz else if (fts->children || f->fts_info == FTS_D || f->fts_info == FTS_SL)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (fts->top)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz fts->bot = fts->bot->fts_link = f;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz fts->top = fts->bot = f;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz /*
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz * terminal node
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz */
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz f->fts_path = PATH(fts, fts->path, 1);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz f->fts_pathlen = fts->endbase - f->fts_path + f->fts_namelen;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz f->fts_accpath = ACCESS(fts, f);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz fts->previous = fts->current;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz fts->current = f;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz fts->state = FTS_terminal;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz goto note;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz /*
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz * done with the directory
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz */
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz closedir(fts->dir);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz fts->dir = 0;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (fts->root)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz getlist(&fts->top, &fts->bot, fts->root);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (fts->children)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz * try moving back to parent dir
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz fts->base[fts->baselen] = 0;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (fts->cd <= 0)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz f = fts->current->fts_parent;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (fts->cd < 0
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz || f != fts->curdir
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz || !fts->dotdot
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz || !SAME(f->fts_statp, fts->dotdot->fts_statp)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz || fts->pwd && fts->pwd->symlink
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz || (fts->cd = chdir("..")) < 0
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz#ifdef verify
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz || stat(".", &sb) < 0
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz || !SAME(&sb, fts->dotdot->fts_statp)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz#endif
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz )
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz fts->cd = setpdir(fts->home, fts->path, fts->base);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (fts->pwd)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz fts->pwd = fts->pwd->pwd;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz fts->curdir = fts->cd ? 0 : f;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz f = fts->current;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz fts->link = f->fts_link;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz f->fts_link = fts->top;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz f->fts_path = PATH(fts, fts->path, f->fts_level);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz f->fts_pathlen = (fts->base - f->fts_path) + f->fts_namelen;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin f->fts_accpath = ACCESS(fts, f);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz fts->state = FTS_children_return;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto note;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz /*FALLTHROUGH*/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz case FTS_children_resume:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fts->base[fts->baselen] = 0;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (fts->top)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz fts->bot->fts_link = fts->todo;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz fts->todo = fts->top;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz fts->top = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz /*FALLTHROUGH*/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz case FTS_popstack:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz /*
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz * pop objects completely processed
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz fts->nd = 0;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz f = fts->current;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz /*FALLTHROUGH*/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz case FTS_popstack_resume:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz while (fts->todo && f == fts->todo)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz t = f->fts_parent;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if ((f->fts_info & FTS_DP) == FTS_D)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz * delete from <dev,ino> tree
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (f != fts->diroot)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz fts->diroot = search(f, fts->diroot, statcmp, 0);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz fts->diroot = deleteroot(fts->diroot);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (f == fts->curdir)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz fts->nd++;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz fts->curdir = t;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz * perform post-order processing
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (!(fts->flags & FTS_NOPOSTORDER) &&
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz f->status != FTS_SKIP &&
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz f->status != FTS_NOPOSTORDER)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz /*
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz * move to parent dir
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz */
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (fts->nd > 0)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz fts->cd = popdirs(fts);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (fts->cd < 0)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz fts->cd = setpdir(fts->home, fts->path, fts->base);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz fts->curdir = fts->cd ? 0 : t;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz f->fts_info = FTS_DP;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz f->fts_path = PATH(fts, fts->path, f->fts_level);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz f->fts_pathlen = (fts->base - f->fts_path) + f->fts_namelen;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz f->fts_accpath = ACCESS(fts, f);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz /*
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz * re-stat to update nlink/times
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz */
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz stat(f->fts_accpath, f->fts_statp);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz fts->link = f->fts_link;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz f->fts_link = 0;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz fts->state = FTS_popstack_return;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz goto note;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz /*
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz * reset base
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (fts->base > fts->path + t->fts_namelen)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz fts->base--;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz *fts->base = 0;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz fts->base -= t->fts_namelen;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz /*
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz * try again or delete from top of stack
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz */
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (f->status == FTS_AGAIN)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz f->fts_info = FTS_D;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz f->status = 0;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz else
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz fts->todo = fts->todo->fts_link;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz drop(fts, f);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz f = t;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz * reset current directory
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (fts->nd > 0 && popdirs(fts) < 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz pathcd(fts->home, NiL);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz fts->curdir = 0;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz fts->cd = -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (fts->todo)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (*fts->base)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz fts->base += f->fts_namelen;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (*(fts->base - 1) != '/')
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz *fts->base++ = '/';
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz *fts->base = 0;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz f = fts->todo;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz fts->state = FTS_todo;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz case FTS_children_return:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz f = fts->current;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz f->fts_link = fts->link;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz /*
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz * chdir down again
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz i = f->fts_info != FTS_DNX;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz n = f->status == FTS_SKIP;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (!n && fts->cd == 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if ((fts->cd = chdir(fts->base)) < 0)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz pathcd(fts->home, NiL);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz else if (fts->pwd != f)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz f->pwd = fts->pwd;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz fts->pwd = f;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz fts->curdir = fts->cd ? 0 : f;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz /*
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz * prune
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (fts->base[fts->baselen - 1] != '/')
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz fts->base[fts->baselen] = '/';
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz for (fts->bot = 0, f = fts->top; f; )
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (n || f->status == FTS_SKIP)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (fts->bot)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz fts->bot->fts_link = f->fts_link;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz else
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz fts->top = f->fts_link;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz drop(fts, f);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz f = fts->bot ? fts->bot->fts_link : fts->top;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (fts->children > 1 && i)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (f->status == FTS_STAT)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz info(fts, f, NiL, f->fts_statp, 0);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz else if (f->fts_info == FTS_NSOK && !SKIP(fts, f))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz s = f->fts_name;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (fts->cd)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz memcpy(fts->endbase, s, f->fts_namelen + 1);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz s = fts->path;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz info(fts, f, s, f->fts_statp, fts->flags);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz fts->bot = f;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz f = f->fts_link;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz fts->children = 0;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz fts->state = FTS_children_resume;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz case FTS_popstack_return:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz f = fts->todo;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz f->fts_link = fts->link;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz f->fts_info = f->status == FTS_AGAIN ? FTS_DP : 0;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz fts->state = FTS_popstack_resume;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz case FTS_preorder_return:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz f = fts->current;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz f->fts_link = fts->link;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz /*
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz * follow symlink if asked to
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (f->status == FTS_FOLLOW)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz f->status = 0;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (f->fts_info == FTS_SL || ISTYPE(f, DT_LNK) || f->fts_info == FTS_NSOK)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz info(fts, f, f->fts_accpath, f->fts_statp, 0);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (f->fts_info != FTS_SL)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz fts->state = FTS_preorder;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz continue;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz /*
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz * about to prune this f and already at home
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (fts->cd == 0 && f->fts_level == 0 && f->nd)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz fts->cd = -1;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz fts->state = FTS_preorder_resume;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz case FTS_terminal:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz f = fts->current;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (f->status == FTS_FOLLOW)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz f->status = 0;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (f->fts_info == FTS_SL || ISTYPE(f, DT_LNK) || f->fts_info == FTS_NSOK)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz info(fts, f, f->fts_accpath, f->fts_statp, 0);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (f->symlink && f->fts_info != FTS_SL)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (!(f->fts_link = fts->top))
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz fts->bot = f;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz fts->top = f;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz fts->current = fts->previous;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz fts->state = FTS_readdir;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz continue;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz f = f->fts_parent;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz drop(fts, fts->current);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz fts->current = f;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz fts->state = FTS_readdir;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz case FTS_error:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz default:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz fts->fts_errno = EINVAL;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz fts->state = FTS_error;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin note:
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz#if __OBSOLETE__ < 20140101
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz f->_fts_pathlen = (unsigned short)f->fts_pathlen;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (p = notify; p; p = p->next)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((n = (*p->notifyf)(fts, f, p->context)) > 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (n < 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fts->fts_errno = EINVAL;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fts->state = FTS_error;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return f;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * set stream or entry flags
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinfts_set(register FTS* fts, register FTSENT* f, int status)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (fts || !f || f->fts->current != f)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch (status)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case FTS_AGAIN:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case FTS_FOLLOW:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(f->fts_info & FTS_SL))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case FTS_NOPOSTORDER:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case FTS_SKIP:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((f->fts_info & (FTS_D|FTS_P)) != FTS_D)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin default:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin f->status = status;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * return the list of child entries
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinFTSENT*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinfts_children(register FTS* fts, int flags)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register FTSENT* f;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch (fts->state)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 0:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (fts->comparf)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz order(fts);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fts->state = FTS_top_return;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return fts->todo;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case FTS_preorder_return:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fts->children = ((flags | fts->flags) & FTS_NOSTAT) ? 2 : 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (f = fts_read(fts))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin f = f->fts_link;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return f;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * return default (FTS_LOGICAL|FTS_META|FTS_PHYSICAL|FTS_SEEDOTDIR) flags
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * conditioned by astconf()
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinfts_flags(void)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char* s;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s = astconf("PATH_RESOLVE", NiL, NiL);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (streq(s, "logical"))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return FTS_LOGICAL;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (streq(s, "physical"))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return FTS_PHYSICAL|FTS_SEEDOTDIR;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return FTS_META|FTS_PHYSICAL|FTS_SEEDOTDIR;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin/*
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin * return 1 if ent is mounted on a local filesystem
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinint
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinfts_local(FTSENT* ent)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin{
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#ifdef ST_LOCAL
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin struct statvfs fs;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return statvfs(ent->fts_path, &fs) || (fs.f_flag & ST_LOCAL);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return !strgrpmatch(fmtfs(ent->fts_statp), "([an]fs|samb)", NiL, 0, STR_LEFT|STR_ICASE);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#endif
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin}
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * close an open fts stream
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinfts_close(register FTS* fts)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register FTSENT* f;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register FTSENT* x;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (fts->dir)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin closedir(fts->dir);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (fts->cd == 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pathcd(fts->home, NiL);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin free(fts->home);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (fts->state == FTS_children_return)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fts->current->fts_link = fts->link;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (fts->top)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fts->bot->fts_link = fts->todo;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fts->todo = fts->top;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (f = fts->todo; f; f = x)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin x = f->fts_link;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin free(f);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (f = fts->free; f; f = x)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin x = f->fts_link;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin free(f);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin free(fts);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * register function to be called for each fts_read() entry
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin * context==0 => unregister notifyf
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinfts_notify(Notify_f notifyf, void* context)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Notify_t* np;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin register Notify_t* pp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if (context)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if (!(np = newof(0, Notify_t, 1, 0)))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return -1;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin np->notifyf = notifyf;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin np->context = context;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin np->next = notify;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin notify = np;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin for (np = notify, pp = 0; np; pp = np, np = np->next)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if (np->notifyf == notifyf)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if (pp)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin pp->next = np->next;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin notify = np->next;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin free(np);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return -1;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}