summaryrefslogtreecommitdiff
path: root/usr.bin/find/function.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr.bin/find/function.c')
-rw-r--r--usr.bin/find/function.c193
1 files changed, 62 insertions, 131 deletions
diff --git a/usr.bin/find/function.c b/usr.bin/find/function.c
index 02540f2..be880e9 100644
--- a/usr.bin/find/function.c
+++ b/usr.bin/find/function.c
@@ -32,19 +32,15 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
-#ifndef lint
-#if 0
-static char sccsid[] = "from: @(#)function.c 8.10 (Berkeley) 5/4/95";
-#else
-__RCSID("$NetBSD: function.c,v 1.77 2018/09/04 15:16:15 kre Exp $");
-#endif
-#endif /* not lint */
-
+#include <sys/ioctl.h>
#include <sys/param.h>
#include <sys/stat.h>
+#include <sys/statvfs.h>
#include <sys/wait.h>
#include <sys/mount.h>
+#include <bsd/sys/time.h>
+
+#include <linux/fs.h>
#include <dirent.h>
#include <err.h>
@@ -54,14 +50,14 @@ __RCSID("$NetBSD: function.c,v 1.77 2018/09/04 15:16:15 kre Exp $");
#include <grp.h>
#include <inttypes.h>
#include <limits.h>
+#include <mntent.h>
#include <pwd.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <tzfile.h>
#include <unistd.h>
-#include <util.h>
+#include <bsd/unistd.h>
#include "find.h"
@@ -181,7 +177,7 @@ find_parsenum(PLAN *plan, const char *option, const char *vp, char *endch)
* and endchar points to the beginning of the string we know we have
* a syntax error.
*/
- value = strtoq(str, &endchar, 10);
+ value = strtoll(str, &endchar, 10);
if (value == 0 && endchar == str)
errx(1, "%s: %s: illegal numeric value", option, vp);
if (endchar[0] && (endch == NULL || endchar[0] != *endch))
@@ -227,6 +223,7 @@ find_parsedate(PLAN *plan, const char *option, const char *vp)
int
f_amin(PLAN *plan, FTSENT *entry)
{
+#define SECSPERMIN 60
COMPARE((now - entry->fts_statp->st_atime +
SECSPERMIN - 1) / SECSPERMIN, plan->t_data);
}
@@ -312,6 +309,7 @@ c_asince(char ***argvp, int isok, char *opt)
int
f_atime(PLAN *plan, FTSENT *entry)
{
+#define SECSPERDAY 24*60*60
COMPARE((now - entry->fts_statp->st_atime +
SECSPERDAY - 1) / SECSPERDAY, plan->t_data);
}
@@ -450,8 +448,10 @@ c_ctime(char ***argvp, int isok, char *opt)
* Always true. Makes its best shot and continues on regardless.
*/
int
-f_delete(PLAN *plan __unused, FTSENT *entry)
+f_delete(PLAN *plan, FTSENT *entry)
{
+ int flags;
+ FILE *file;
/* ignore these from fts */
if (strcmp(entry->fts_accpath, ".") == 0 ||
strcmp(entry->fts_accpath, "..") == 0)
@@ -468,13 +468,18 @@ f_delete(PLAN *plan __unused, FTSENT *entry)
if (entry->fts_level > 0 && strchr(entry->fts_accpath, '/') != NULL)
errx(1, "-delete: %s: relative path potentially not safe",
entry->fts_accpath);
-
- /* Turn off user immutable bits if running as root */
- if ((entry->fts_statp->st_flags & (UF_APPEND|UF_IMMUTABLE)) &&
- !(entry->fts_statp->st_flags & (SF_APPEND|SF_IMMUTABLE)) &&
- geteuid() == 0)
- chflags(entry->fts_accpath,
- entry->fts_statp->st_flags &= ~(UF_APPEND|UF_IMMUTABLE));
+
+ file = fopen(entry->fts_name, "r");
+ if (file == NULL) {
+ warn("couldn't check flags for %s", entry->fts_name);
+ } else {
+ ioctl(fileno(file), FS_IOC_GETFLAGS, &flags);
+ /* turn off immutable bit if running as root */
+ if ((geteuid() == 0) && (flags & FS_IMMUTABLE_FL)) {
+ flags = flags & ~FS_IMMUTABLE_FL;
+ ioctl(fileno(file), FS_IOC_SETFLAGS, &flags);
+ }
+ }
/* rmdir directories, unlink everything else */
if (S_ISDIR(entry->fts_statp->st_mode)) {
@@ -490,7 +495,7 @@ f_delete(PLAN *plan __unused, FTSENT *entry)
}
PLAN *
-c_delete(char ***argvp __unused, int isok, char *opt)
+c_delete(char ***argvp, int isok, char *opt)
{
ftsoptions &= ~FTS_NOSTAT; /* no optimize */
@@ -762,7 +767,7 @@ c_exec(char ***argvp, int isok, char *opt)
new->ep_maxargs = ARG_MAX / (sizeof (char *) + 16);
if (new->ep_maxargs > 5000)
new->ep_maxargs = 5000;
- new->e_argv = emalloc((cnt + new->ep_maxargs)
+ new->e_argv = malloc((cnt + new->ep_maxargs)
* sizeof(*new->e_argv));
/* We start stuffing arguments after the user's last one. */
@@ -790,21 +795,21 @@ c_exec(char ***argvp, int isok, char *opt)
* Allocate, and then initialize current, base, and
* end pointers.
*/
- new->ep_p = new->ep_bbp = emalloc(bufsize + 1);
+ new->ep_p = new->ep_bbp = malloc(bufsize + 1);
new->ep_ebp = new->ep_bbp + bufsize - 1;
new->ep_rval = 0;
} else { /* !F_PLUSSET */
cnt = ap - *argvp + 1;
- new->e_argv = emalloc(cnt * sizeof(*new->e_argv));
- new->e_orig = emalloc(cnt * sizeof(*new->e_orig));
- new->e_len = emalloc(cnt * sizeof(*new->e_len));
+ new->e_argv = malloc(cnt * sizeof(*new->e_argv));
+ new->e_orig = malloc(cnt * sizeof(*new->e_orig));
+ new->e_len = malloc(cnt * sizeof(*new->e_len));
for (argv = *argvp, cnt = 0; argv < ap; ++argv, ++cnt) {
new->e_orig[cnt] = *argv;
for (p = *argv; *p; ++p)
if (p[0] == '{' && p[1] == '}') {
new->e_argv[cnt] =
- emalloc(MAXPATHLEN);
+ malloc(MAXPATHLEN);
new->e_len[cnt] = MAXPATHLEN;
break;
}
@@ -893,15 +898,15 @@ c_execdir(char ***argvp, int isok, char *opt)
}
cnt = ap - *argvp + 1;
- new->e_argv = emalloc(cnt * sizeof(*new->e_argv));
- new->e_orig = emalloc(cnt * sizeof(*new->e_orig));
- new->e_len = emalloc(cnt * sizeof(*new->e_len));
+ new->e_argv = malloc(cnt * sizeof(*new->e_argv));
+ new->e_orig = malloc(cnt * sizeof(*new->e_orig));
+ new->e_len = malloc(cnt * sizeof(*new->e_len));
for (argv = *argvp, cnt = 0; argv < ap; ++argv, ++cnt) {
new->e_orig[cnt] = *argv;
for (p = *argv; *p; ++p)
if (p[0] == '{' && p[1] == '}') {
- new->e_argv[cnt] = emalloc(MAXPATHLEN);
+ new->e_argv[cnt] = malloc(MAXPATHLEN);
new->e_len[cnt] = MAXPATHLEN;
break;
}
@@ -953,48 +958,6 @@ c_false(char ***argvp, int isok, char *opt)
return (palloc(N_FALSE, f_false));
}
-
-/*
- * -flags [-]flags functions --
- */
-int
-f_flags(PLAN *plan, FTSENT *entry)
-{
- u_int32_t flags;
-
- flags = entry->fts_statp->st_flags;
- if (plan->flags == F_ATLEAST)
- return ((plan->f_data | flags) == flags);
- else
- return (flags == plan->f_data);
- /* NOTREACHED */
-}
-
-PLAN *
-c_flags(char ***argvp, int isok, char *opt)
-{
- char *flags = **argvp;
- PLAN *new;
- u_long flagset;
-
- (*argvp)++;
- ftsoptions &= ~FTS_NOSTAT;
-
- new = palloc(N_FLAGS, f_flags);
-
- if (*flags == '-') {
- new->flags = F_ATLEAST;
- ++flags;
- }
-
- flagset = 0;
- if ((strcmp(flags, "none") != 0) &&
- (string_to_flags(&flags, &flagset, NULL) != 0))
- errx(1, "%s: %s: illegal flags string", opt, flags);
- new->f_data = flagset;
- return (new);
-}
-
/*
* -follow functions --
*
@@ -1042,7 +1005,7 @@ c_fprint(char ***argvp, int isok, char *opt)
(*argvp)++;
return (new);
}
-
+#define MNT_RDONLY 0x01
/*
* -fstype functions --
*
@@ -1051,57 +1014,33 @@ c_fprint(char ***argvp, int isok, char *opt)
int
f_fstype(PLAN *plan, FTSENT *entry)
{
- static dev_t curdev; /* need a guaranteed illegal dev value */
- static int first = 1;
- struct statvfs sb;
- static short val;
- static char fstype[sizeof(sb.f_fstypename)];
- char *p, save[2];
-
- memset(&save, 0, sizeof save); /* XXX gcc */
-
- /* Only check when we cross mount point. */
- if (first || curdev != entry->fts_statp->st_dev) {
- curdev = entry->fts_statp->st_dev;
+ static char *fstype = NULL;
+ FILE *file;
+ struct mntent *mnt;
+ int flags;
+ char *filename = strdup(entry->fts_name);
+ char *temp = strrchr(filename, '/');
+ temp[0] = '\0';
+
+ file = setmntent("/etc/mtab", "r");
+ if (file == NULL) {
+ err(1, "couldn't read mount table");
+ }
- /*
- * Statfs follows symlinks; find wants the link's file system,
- * not where it points.
- */
- if (entry->fts_info == FTS_SL ||
- entry->fts_info == FTS_SLNONE) {
- if ((p = strrchr(entry->fts_accpath, '/')) != NULL)
- ++p;
- else
- p = entry->fts_accpath;
- save[0] = p[0];
- p[0] = '.';
- save[1] = p[1];
- p[1] = '\0';
-
- } else
- p = NULL;
-
- if (statvfs(entry->fts_accpath, &sb))
- err(1, "%s", entry->fts_accpath);
-
- if (p) {
- p[0] = save[0];
- p[1] = save[1];
+ while ((mnt = getmntent(file)) != NULL) {
+ if (!strncmp(mnt->mnt_dir, filename, strlen(mnt->mnt_dir))) {
+ fstype = strdup(mnt->mnt_type);
+ if (strstr(mnt->mnt_opts, MNTOPT_RO) != NULL) {
+ flags |= MNT_RDONLY;
+ }
+ break;
}
-
- first = 0;
-
- /*
- * Further tests may need both of these values, so
- * always copy both of them.
- */
- val = sb.f_flag;
- strlcpy(fstype, sb.f_fstypename, sizeof(fstype));
}
+ endmntent(file);
+
switch (plan->flags) {
case F_MTFLAG:
- return (val & plan->mt_data);
+ return (flags & plan->mt_data);
case F_MTTYPE:
return (strncmp(fstype, plan->c_data, sizeof(fstype)) == 0);
default:
@@ -1121,13 +1060,6 @@ c_fstype(char ***argvp, int isok, char *opt)
new = palloc(N_FSTYPE, f_fstype);
switch (*arg) {
- case 'l':
- if (!strcmp(arg, "local")) {
- new->flags = F_MTFLAG;
- new->mt_data = MNT_LOCAL;
- return (new);
- }
- break;
case 'r':
if (!strcmp(arg, "rdonly")) {
new->flags = F_MTFLAG;
@@ -1320,6 +1252,7 @@ c_mindepth(char ***argvp, int isok, char *opt)
int
f_mmin(PLAN *plan, FTSENT *entry)
{
+#define SECSPERMIN 60
COMPARE((now - entry->fts_statp->st_mtime + SECSPERMIN - 1) /
SECSPERMIN, plan->t_data);
}
@@ -1456,8 +1389,7 @@ c_newer(char ***argvp, int isok, char *opt)
int
f_nogroup(PLAN *plan, FTSENT *entry)
{
-
- return (group_from_gid(entry->fts_statp->st_gid, 1) ? 0 : 1);
+ return getgrgid(entry->fts_statp->st_gid) != NULL;
}
PLAN *
@@ -1477,8 +1409,7 @@ c_nogroup(char ***argvp, int isok, char *opt)
int
f_nouser(PLAN *plan, FTSENT *entry)
{
-
- return (user_from_uid(entry->fts_statp->st_uid, 1) ? 0 : 1);
+ return getpwuid(entry->fts_statp->st_uid) != NULL;
}
PLAN *