Deleted Added
full compact
1/*-
2 * Copyright (c) 1990, 1993, 1994
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 23 unchanged lines hidden (view full) ---

32 *
33 * $OpenBSD: fts.c,v 1.22 1999/10/03 19:22:22 millert Exp $
34 */
35
36#if defined(LIBC_SCCS) && !defined(lint)
37static char sccsid[] = "@(#)fts.c 8.6 (Berkeley) 8/14/94";
38#endif /* LIBC_SCCS and not lint */
39#include <sys/cdefs.h>
40__FBSDID("$FreeBSD: head/lib/libc/gen/fts-compat.c 129052 2004-05-08 15:09:02Z peadar $");
40__FBSDID("$FreeBSD: head/lib/libc/gen/fts-compat.c 129161 2004-05-12 21:38:39Z peadar $");
41
42#include "namespace.h"
43#include <sys/types.h>
43#include <sys/param.h>
45#include <sys/stat.h>
44#include <sys/mount.h>
45#include <sys/stat.h>
46
47#include <dirent.h>
48#include <errno.h>
49#include <fcntl.h>
50#include <fts.h>
51#include <stdlib.h>
52#include <string.h>
53#include <unistd.h>

--- 4 unchanged lines hidden (view full) ---

58static void fts_lfree(FTSENT *);
59static void fts_load(FTS *, FTSENT *);
60static size_t fts_maxarglen(char * const *);
61static void fts_padjust(FTS *, FTSENT *);
62static int fts_palloc(FTS *, size_t);
63static FTSENT *fts_sort(FTS *, FTSENT *, int);
64static u_short fts_stat(FTS *, FTSENT *, int);
65static int fts_safe_changedir(FTS *, FTSENT *, int, char *);
67static int fts_ufslinks(FTS *sp, const FTSENT *ent);
66static int fts_ufslinks(FTS *, const FTSENT *);
67
68#define ISDOT(a) (a[0] == '.' && (!a[1] || (a[1] == '.' && !a[2])))
69
70#define CLR(opt) (sp->fts_options &= ~(opt))
71#define ISSET(opt) (sp->fts_options & (opt))
72#define SET(opt) (sp->fts_options |= (opt))
73
74#define FCHDIR(sp, fd) (!ISSET(FTS_NOCHDIR) && fchdir(fd))
75
76/* fts_build flags */
77#define BCHILD 1 /* fts_children */
78#define BNAMES 2 /* fts_children, names only */
79#define BREAD 3 /* fts_read */
80
81/*
83 * Internal representation of FTS, including extra implementation details.
84 * The FTS returned from fts_open is ftsp_fts from this structure, and it's
85 * fts_priv in turn points back to this internal version. i.e. for a given
86 * fts_private *priv: &priv->fts_fts == (FTS *)f == priv->fts_fts.fts_priv
82 * Internal representation of an FTS, including extra implementation
83 * details. The FTS returned from fts_open points to this structure's
84 * ftsp_fts member (and can be cast to an _fts_private as required)
85 */
86struct _fts_private {
89 FTS ftsp_fts;
90 struct statfs ftsp_statfs;
91 dev_t ftsp_dev;
92 int ftsp_linksreliable;
87 FTS ftsp_fts;
88 struct statfs ftsp_statfs;
89 dev_t ftsp_dev;
90 int ftsp_linksreliable;
91};
92
93/*
96 * The "FTS_NOSTAT" option can avoid a lot of calls to stat(2) if it knows
97 * that a directory could not possibly have subdirectories. This is decided
98 * by looking at the link count: A subdirectory would increment its parent's
99 * link count by virtue of its own ".." entry.
100 * This assumption only holds for UFS-like filesystems that implement links
101 * and directories this way, so we must punt for others.
94 * The "FTS_NOSTAT" option can avoid a lot of calls to stat(2) if it
95 * knows that a directory could not possibly have subdirectories. This
96 * is decided by looking at the link count: a subdirectory would
97 * increment its parent's link count by virtue of its own ".." entry.
98 * This assumption only holds for UFS-like filesystems that implement
99 * links and directories this way, so we must punt for others.
100 */
101
102static const char *ufslike_filesystems[] = {
103 "ufs",
104 "nfs",
105 "nfs4",
106 "ext2fs",
107 0

--- 14 unchanged lines hidden (view full) ---

122
123 /* Options check. */
124 if (options & ~FTS_OPTIONMASK) {
125 errno = EINVAL;
126 return (NULL);
127 }
128
129 /* Allocate/initialize the stream */
132 if ((priv = malloc(sizeof(struct _fts_private))) == NULL)
130 if ((priv = malloc(sizeof(*priv))) == NULL)
131 return (NULL);
134 memset(priv, 0, sizeof(struct _fts_private));
132 memset(priv, 0, sizeof(*priv));
133 sp = &priv->ftsp_fts;
134 sp->fts_compar = compar;
135 sp->fts_options = options;
138 sp->fts_priv = priv;
136
137 /* Shush, GCC. */
138 tmp = NULL;
139
140 /* Logical walks turn on NOCHDIR; symbolic links are too hard. */
141 if (ISSET(FTS_LOGICAL))
142 SET(FTS_NOCHDIR);
143

--- 1050 unchanged lines hidden (view full) ---

1194 * Check if the filesystem for "ent" has UFS-style links.
1195 */
1196static int
1197fts_ufslinks(FTS *sp, const FTSENT *ent)
1198{
1199 struct _fts_private *priv;
1200 const char **cpp;
1201
1205 priv = sp->fts_priv;
1202 priv = (struct _fts_private *)sp;
1203 /*
1204 * If this node's device is different from the previous, grab
1205 * the filesystem information, and decide on the reliability
1206 * of the link information from this filesystem for stat(2)
1207 * avoidance.
1208 */
1209 if (priv->ftsp_dev != ent->fts_dev) {
1210 if (statfs(ent->fts_path, &priv->ftsp_statfs) != -1) {

--- 5 unchanged lines hidden (view full) ---

1216 priv->ftsp_linksreliable = 1;
1217 break;
1218 }
1219 }
1220 } else {
1221 priv->ftsp_linksreliable = 0;
1222 }
1223 }
1227 return priv->ftsp_linksreliable;
1224 return (priv->ftsp_linksreliable);
1225}