Esempio n. 1
0
/**
 * -[acm]{min,time} tests.
 */
bool eval_acmtime(const struct expr *expr, struct eval_state *state) {
	const struct stat *statbuf = fill_statbuf(state);
	if (!statbuf) {
		return false;
	}

	const struct timespec *time;
	switch (expr->timefield) {
	case ATIME:
		time = &statbuf->st_atim;
		break;
	case CTIME:
		time = &statbuf->st_ctim;
		break;
	case MTIME:
		time = &statbuf->st_mtim;
		break;
	}

	time_t diff = timespec_diff(&expr->reftime, time);
	switch (expr->timeunit) {
	case MINUTES:
		diff /= 60;
		break;
	case DAYS:
		diff /= 60*60*24;
		break;
	}

	return do_cmp(expr, diff);
}
Esempio n. 2
0
/**
 * -i?lname test.
 */
bool eval_lname(const struct expr *expr, struct eval_state *state) {
	struct BFTW *ftwbuf = state->ftwbuf;
	if (ftwbuf->typeflag != BFTW_LNK) {
		return false;
	}

	const struct stat *statbuf = fill_statbuf(state);
	if (!statbuf) {
		return false;
	}

	size_t size = statbuf->st_size + 1;
	char *name = malloc(size);
	if (!name) {
		eval_error(state);
		return false;
	}

	ssize_t ret = readlinkat(ftwbuf->at_fd, ftwbuf->at_path, name, size);
	if (ret < 0) {
		eval_error(state);
		return false;
	} else if (ret >= size) {
		return false;
	}

	name[ret] = '\0';

	bool match = fnmatch(expr->sdata, name, expr->idata) == 0;
	free(name);
	return match;
}
Esempio n. 3
0
/**
 * -samefile test.
 */
bool eval_samefile(const struct expr *expr, struct eval_state *state) {
	const struct stat *statbuf = fill_statbuf(state);
	if (!statbuf) {
		return false;
	}

	return statbuf->st_dev == expr->dev && statbuf->st_ino == expr->ino;
}
Esempio n. 4
0
/**
 * -links test.
 */
bool eval_links(const struct expr *expr, struct eval_state *state) {
	const struct stat *statbuf = fill_statbuf(state);
	if (!statbuf) {
		return false;
	}

	return do_cmp(expr, statbuf->st_nlink);
}
Esempio n. 5
0
/**
 * -print action.
 */
bool eval_print(const struct expr *expr, struct eval_state *state) {
	const struct colors *colors = state->cmdline->stdout_colors;
	if (colors) {
		fill_statbuf(state);
	}

	pretty_print(colors, state->ftwbuf);
	return true;
}
Esempio n. 6
0
/*
 * -ENOENT, -ENOTDIR, -ENAMETOOLONG
 */
int sys_stat(const char *path, struct stat *buf)
{
	uint64_t inum;

	inum = name_i(path);
	if (inum < 0)
		return inum;

	fill_statbuf(inum, buf);
	return 0;
}
Esempio n. 7
0
int sys_fstat(int fd, struct stat *buf)
{
	struct file *file;

	file = unrolled_lookup(&current->fdtable, fd);
	if (file == NULL)
		return -EBADF;

	fill_statbuf(file->inum, buf);
	return 0;
}
Esempio n. 8
0
/**
 * -empty test.
 */
bool eval_empty(const struct expr *expr, struct eval_state *state) {
	bool ret = false;
	struct BFTW *ftwbuf = state->ftwbuf;

	if (ftwbuf->typeflag == BFTW_DIR) {
		int dfd = openat(ftwbuf->at_fd, ftwbuf->at_path, O_DIRECTORY);
		if (dfd < 0) {
			eval_error(state);
			goto done;
		}

		DIR *dir = fdopendir(dfd);
		if (!dir) {
			eval_error(state);
			close(dfd);
			goto done;
		}

		ret = true;

		struct dirent *de;
		while ((de = readdir(dir)) != NULL) {
			if (strcmp(de->d_name, ".") != 0 && strcmp(de->d_name, "..") != 0) {
				ret = false;
				break;
			}
		}

		closedir(dir);
	} else {
		const struct stat *statbuf = fill_statbuf(state);
		if (statbuf) {
			ret = statbuf->st_size == 0;
		}
	}

done:
	return ret;
}
Esempio n. 9
0
/**
 * -[ac]?newer tests.
 */
bool eval_acnewer(const struct expr *expr, struct eval_state *state) {
	const struct stat *statbuf = fill_statbuf(state);
	if (!statbuf) {
		return false;
	}

	const struct timespec *time;
	switch (expr->timefield) {
	case ATIME:
		time = &statbuf->st_atim;
		break;
	case CTIME:
		time = &statbuf->st_ctim;
		break;
	case MTIME:
		time = &statbuf->st_mtim;
		break;
	}

	return time->tv_sec > expr->reftime.tv_sec
		|| (time->tv_sec == expr->reftime.tv_sec && time->tv_nsec > expr->reftime.tv_nsec);
}