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* A copy of the License is available at *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Information and Software Systems Research *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* AT&T Research *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Florham Park NJ *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Glenn Fowler <gsf@research.att.com> *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* David Korn <dgk@research.att.com> *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Phong Vo <kpv@research.att.com> *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin***********************************************************************/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Phong Vo
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Glenn Fowler
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * AT&T Research
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * fts implementation unwound from the kpv ftwalk() of 1988-10-30
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chintypedef int (*Compar_f)(struct Ftsent* const*, struct Ftsent* const*);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unsigned char children; \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unsigned char fs3d; \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unsigned char nostat; \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * NOTE: <ftwalk.h> relies on status and statb being the first two elements
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define drop(p,f) (((f)->fts_namelen < MINNAME) ? ((f)->fts_link = (p)->free, (p)->free = (f)) : (free(f), (p)->free))
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 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#define SKIP(p,f) ((f)->fts_parent->must == 0 && SKIPLINK(p,f))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * NOTE: a malicious dir rename() could change .. underfoot so we
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * must always verify; undef verify to enable the unsafe code
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * FTS_NOSTAT requires a dir with
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * D_TYPE(&dirent_t)!=DT_UNKNOWN
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * st_nlink>=2
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * allocate an FTSENT node
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainznode(FTS* fts, FTSENT* parent, register char* name, register size_t namelen)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register FTSENT* f;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = (namelen < MINNAME ? MINNAME : namelen + 1) - sizeof(int);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin f->fts_level = (f->fts_parent = parent)->fts_level + 1;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz f->_fts_namelen = (unsigned short)f->fts_namelen;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * compare directories by device/inode
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * hack for NFS where <dev,ino> may not uniquely identify objects
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * search trees with top-down splaying (a la Tarjan and Sleator)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * when used for insertion sort, this implements a stable sort
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)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinsearch(FTSENT* e, FTSENT* root, int(*comparf)(FTSENT* const*, FTSENT* const*), int insert)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register FTSENT* t;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * this is the left zig-zig case
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (root->left && (cmp = (*comparf)(&e, &root->left)) <= 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * stick all things > e to the right tree
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * this is the right zig-zig case
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (root->right && (cmp = (*comparf)(&e, &root->right)) >= 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * stick all things <= e to the left tree
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * delete the root element from the tree
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register FTSENT* t;
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
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic void
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chingetlist(register FTSENT** top, register FTSENT** bot, register FTSENT* root)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * set directory when curdir is lost in space
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * note that path and home are in the same buffer
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * set to parent dir
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinsetpdir(register char* home, register char* path, register char* base)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * pop a set of directories
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register FTSENT*f;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char* s;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char* e;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *s++ = '.';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *s++ = '.';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *s++ = '/';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return (verify && (stat(".", &sb) < 0 || !SAME(&sb, f->fts_statp))) ? -1 : 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * initialize st from path and fts_info from st
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chininfo(FTS* fts, register FTSENT* f, const char* path, struct stat* sp, int flags)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!f->symlink && (ISTYPE(f, DT_UNKNOWN) || ISTYPE(f, DT_LNK)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return -1;
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 register FTSENT* f;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin metaphysical = (fts->flags & (FTS_META|FTS_PHYSICAL)) == (FTS_META|FTS_PHYSICAL);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * make elements
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin f->fts_namelen = (fts->flags & FTS_SEEDOTDIR) ? strlen(path) : (pathcanon(path, 0) - path);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (*s == '/')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (*path++ = *s++);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (s = path + strlen(path); s > path && *(s - 1) == '/'; s--);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz f->_fts_namelen = (unsigned short)f->fts_namelen;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * don't let any standards committee get
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * away with calling your idea a hack
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (metaphysical && f->fts_info == FTS_SL && stat(path, &st) >= 0)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz * order fts->todo if fts->comparf != 0
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 * add space for "/." used in testing FTS_DNX
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fts->homesize = ((fts->homesize + inc + 4) / PATH_MAX + 1) * PATH_MAX;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * open a new fts stream on pathnames
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinfts_open(char* const* pathnames, int flags, int (*comparf)(FTSENT* const*, FTSENT* const*))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * set up the path work buffer
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(fts->home = newof(fts->home, char, fts->homesize, 0)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * initialize the tippity-top
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin memcpy(fts->parent->fts_accpath = fts->parent->fts_path = fts->parent->fts_name = fts->parent->name, ".", 2);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz fts->parent->_fts_level = (short)fts->parent->fts_level;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * make the list of top elements
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!pathnames || (flags & FTS_ONEPATH) || !*pathnames)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char* v[2];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin v[0] = pathnames && (flags & FTS_ONEPATH) ? (char*)pathnames : ".";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!fts->todo || fts->todo->fts_info == FTS_NS && !fts->todo->fts_link)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * return the next FTS entry
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char* s;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register FTSENT* f;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz /*FALLTHROUGH*/
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz /*FALLTHROUGH*/
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz * process the top object on the stack
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz * initialize the top level
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz * chdir to parent if asked for
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz * add object's name to the path
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if ((fts->baselen = f->fts_namelen) >= (fts->endbuf - fts->base) && resize(fts, fts->baselen))
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz /*FALLTHROUGH*/
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz * check for cycle and open dir
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 else if (!(fts->flags & FTS_TOP) && (!(fts->flags & FTS_XDEV) || f->statb.st_dev == f->fts_parent->statb.st_dev))
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz * buffer is known to be large enough here!
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (!fts->dir && !(fts->dir = opendir(fts->name)))
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 /*FALLTHROUGH*/
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (!fts->dir || f->nd || f->status == FTS_SKIP)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz * FTS_D or FTS_DNX, about to read children
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 /*FALLTHROUGH*/
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (s[0] == '.')
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (s[1] == 0)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz * make a new entry
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz * check for space
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz * don't recurse on . and ..
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz f->fts_statp = &fts->current->fts_parent->statb;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz f->fts_statp = fts->current->fts_parent->fts_statp;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz else if ((fts->nostat || SKIP(fts, f)) && (f->fts_info = FTS_NSOK) || info(fts, f, s, &f->statb, fts->flags))
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 * terminal node
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz f->fts_pathlen = fts->endbase - f->fts_path + f->fts_namelen;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz * done with the directory
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz * try moving back to parent dir
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz fts->cd = setpdir(fts->home, fts->path, fts->base);
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 /*FALLTHROUGH*/
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz /*FALLTHROUGH*/
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz * pop objects completely processed
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz /*FALLTHROUGH*/
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz * delete from <dev,ino> tree
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz fts->diroot = search(f, fts->diroot, statcmp, 0);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz * perform post-order processing
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz * move to parent dir
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz fts->cd = setpdir(fts->home, fts->path, fts->base);
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 * re-stat to update nlink/times
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz * reset base
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz * try again or delete from top of stack
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz * reset current directory
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz * chdir down again
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz else if (f->fts_info == FTS_NSOK && !SKIP(fts, f))
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz f->fts_info = f->status == FTS_AGAIN ? FTS_DP : 0;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz * follow symlink if asked to
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (f->fts_info == FTS_SL || ISTYPE(f, DT_LNK) || f->fts_info == FTS_NSOK)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz * about to prune this f and already at home
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (fts->cd == 0 && f->fts_level == 0 && f->nd)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (f->fts_info == FTS_SL || ISTYPE(f, DT_LNK) || f->fts_info == FTS_NSOK)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz f->_fts_pathlen = (unsigned short)f->fts_pathlen;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (n < 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * set stream or entry flags
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinfts_set(register FTS* fts, register FTSENT* f, int status)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * return the list of child entries
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register FTSENT* f;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fts->children = ((flags | fts->flags) & FTS_NOSTAT) ? 2 : 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * return default (FTS_LOGICAL|FTS_META|FTS_PHYSICAL|FTS_SEEDOTDIR) flags
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * conditioned by astconf()
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char* s;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin * return 1 if ent is mounted on a local filesystem
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return statvfs(ent->fts_path, &fs) || (fs.f_flag & ST_LOCAL);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return !strgrpmatch(fmtfs(ent->fts_statp), "([an]fs|samb)", NiL, 0, STR_LEFT|STR_ICASE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * close an open fts stream
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register FTSENT* f;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register FTSENT* x;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * register function to be called for each fts_read() entry
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin * context==0 => unregister notifyf
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin for (np = notify, pp = 0; np; pp = np, np = np->next)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return -1;