summaryrefslogtreecommitdiffstats
path: root/ctx.c
diff options
context:
space:
mode:
Diffstat (limited to 'ctx.c')
-rw-r--r--ctx.c311
1 files changed, 0 insertions, 311 deletions
diff --git a/ctx.c b/ctx.c
deleted file mode 100644
index 8ba2f38..0000000
--- a/ctx.c
+++ /dev/null
@@ -1,311 +0,0 @@
-/****************************************************************************
- * bfs *
- * Copyright (C) 2015-2022 Tavian Barnes <tavianator@tavianator.com> *
- * *
- * Permission to use, copy, modify, and/or distribute this software for any *
- * purpose with or without fee is hereby granted. *
- * *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES *
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF *
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR *
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES *
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN *
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF *
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. *
- ****************************************************************************/
-
-#include "ctx.h"
-#include "color.h"
-#include "darray.h"
-#include "diag.h"
-#include "expr.h"
-#include "mtab.h"
-#include "pwcache.h"
-#include "stat.h"
-#include "trie.h"
-#include <assert.h>
-#include <errno.h>
-#include <limits.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-const char *debug_flag_name(enum debug_flags flag) {
- switch (flag) {
- case DEBUG_COST:
- return "cost";
- case DEBUG_EXEC:
- return "exec";
- case DEBUG_OPT:
- return "opt";
- case DEBUG_RATES:
- return "rates";
- case DEBUG_SEARCH:
- return "search";
- case DEBUG_STAT:
- return "stat";
- case DEBUG_TREE:
- return "tree";
-
- case DEBUG_ALL:
- break;
- }
-
- assert(!"Unrecognized debug flag");
- return "???";
-}
-
-struct bfs_ctx *bfs_ctx_new(void) {
- struct bfs_ctx *ctx = malloc(sizeof(*ctx));
- if (!ctx) {
- return NULL;
- }
-
- ctx->argv = NULL;
- ctx->paths = NULL;
- ctx->expr = NULL;
- ctx->exclude = NULL;
-
- ctx->mindepth = 0;
- ctx->maxdepth = INT_MAX;
- ctx->flags = BFTW_RECOVER;
- ctx->strategy = BFTW_BFS;
- ctx->optlevel = 3;
- ctx->debug = 0;
- ctx->ignore_races = false;
- ctx->posixly_correct = false;
- ctx->status = false;
- ctx->unique = false;
- ctx->warn = false;
- ctx->xargs_safe = false;
-
- ctx->colors = NULL;
- ctx->colors_error = 0;
- ctx->cout = NULL;
- ctx->cerr = NULL;
-
- ctx->users = NULL;
- ctx->users_error = 0;
- ctx->groups = NULL;
- ctx->groups_error = 0;
-
- ctx->mtab = NULL;
- ctx->mtab_error = 0;
-
- trie_init(&ctx->files);
- ctx->nfiles = 0;
-
- struct rlimit rl;
- if (getrlimit(RLIMIT_NOFILE, &rl) == 0) {
- ctx->nofile_soft = rl.rlim_cur;
- ctx->nofile_hard = rl.rlim_max;
- } else {
- ctx->nofile_soft = 1024;
- ctx->nofile_hard = RLIM_INFINITY;
- }
-
- return ctx;
-}
-
-const struct bfs_users *bfs_ctx_users(const struct bfs_ctx *ctx) {
- struct bfs_ctx *mut = (struct bfs_ctx *)ctx;
-
- if (mut->users_error) {
- errno = mut->users_error;
- } else if (!mut->users) {
- mut->users = bfs_users_parse();
- if (!mut->users) {
- mut->users_error = errno;
- }
- }
-
- return mut->users;
-}
-
-const struct bfs_groups *bfs_ctx_groups(const struct bfs_ctx *ctx) {
- struct bfs_ctx *mut = (struct bfs_ctx *)ctx;
-
- if (mut->groups_error) {
- errno = mut->groups_error;
- } else if (!mut->groups) {
- mut->groups = bfs_groups_parse();
- if (!mut->groups) {
- mut->groups_error = errno;
- }
- }
-
- return mut->groups;
-}
-
-const struct bfs_mtab *bfs_ctx_mtab(const struct bfs_ctx *ctx) {
- struct bfs_ctx *mut = (struct bfs_ctx *)ctx;
-
- if (mut->mtab_error) {
- errno = mut->mtab_error;
- } else if (!mut->mtab) {
- mut->mtab = bfs_mtab_parse();
- if (!mut->mtab) {
- mut->mtab_error = errno;
- }
- }
-
- return mut->mtab;
-}
-
-/**
- * An open file tracked by the bfs context.
- */
-struct bfs_ctx_file {
- /** The file itself. */
- CFILE *cfile;
- /** The path to the file (for diagnostics). */
- const char *path;
-};
-
-CFILE *bfs_ctx_dedup(struct bfs_ctx *ctx, CFILE *cfile, const char *path) {
- struct bfs_stat sb;
- if (bfs_stat(fileno(cfile->file), NULL, 0, &sb) != 0) {
- return NULL;
- }
-
- bfs_file_id id;
- bfs_stat_id(&sb, &id);
-
- struct trie_leaf *leaf = trie_insert_mem(&ctx->files, id, sizeof(id));
- if (!leaf) {
- return NULL;
- }
-
- struct bfs_ctx_file *ctx_file = leaf->value;
- if (ctx_file) {
- ctx_file->path = path;
- return ctx_file->cfile;
- }
-
- leaf->value = ctx_file = malloc(sizeof(*ctx_file));
- if (!ctx_file) {
- trie_remove(&ctx->files, leaf);
- return NULL;
- }
-
- ctx_file->cfile = cfile;
- ctx_file->path = path;
-
- if (cfile != ctx->cout && cfile != ctx->cerr) {
- ++ctx->nfiles;
- }
-
- return cfile;
-}
-
-void bfs_ctx_flush(const struct bfs_ctx *ctx) {
- // Before executing anything, flush all open streams. This ensures that
- // - the user sees everything relevant before an -ok[dir] prompt
- // - output from commands is interleaved consistently with bfs
- // - executed commands can rely on I/O from other bfs actions
- //
- // We do not check errors here, but they will be caught at cleanup time
- // with ferror().
- fflush(NULL);
-}
-
-/** Flush a file and report any errors. */
-static int bfs_ctx_fflush(CFILE *cfile) {
- int ret = 0, error = 0;
- if (ferror(cfile->file)) {
- ret = -1;
- error = EIO;
- }
- if (fflush(cfile->file) != 0) {
- ret = -1;
- error = errno;
- }
-
- errno = error;
- return ret;
-}
-
-/** Close a file tracked by the bfs context. */
-static int bfs_ctx_fclose(struct bfs_ctx *ctx, struct bfs_ctx_file *ctx_file) {
- CFILE *cfile = ctx_file->cfile;
-
- if (cfile == ctx->cout) {
- // Will be checked later
- return 0;
- } else if (cfile == ctx->cerr) {
- // Writes to stderr are allowed to fail silently, unless the same file was used by
- // -fprint, -fls, etc.
- if (ctx_file->path) {
- return bfs_ctx_fflush(cfile);
- } else {
- return 0;
- }
- }
-
- int ret = 0, error = 0;
- if (ferror(cfile->file)) {
- ret = -1;
- error = EIO;
- }
- if (cfclose(cfile) != 0) {
- ret = -1;
- error = errno;
- }
-
- errno = error;
- return ret;
-}
-
-int bfs_ctx_free(struct bfs_ctx *ctx) {
- int ret = 0;
-
- if (ctx) {
- CFILE *cout = ctx->cout;
- CFILE *cerr = ctx->cerr;
-
- bfs_expr_free(ctx->exclude);
- bfs_expr_free(ctx->expr);
-
- bfs_mtab_free(ctx->mtab);
-
- bfs_groups_free(ctx->groups);
- bfs_users_free(ctx->users);
-
- struct trie_leaf *leaf;
- while ((leaf = trie_first_leaf(&ctx->files))) {
- struct bfs_ctx_file *ctx_file = leaf->value;
-
- if (bfs_ctx_fclose(ctx, ctx_file) != 0) {
- if (cerr) {
- bfs_error(ctx, "'%s': %m.\n", ctx_file->path);
- }
- ret = -1;
- }
-
- free(ctx_file);
- trie_remove(&ctx->files, leaf);
- }
- trie_destroy(&ctx->files);
-
- if (cout && bfs_ctx_fflush(cout) != 0) {
- if (cerr) {
- bfs_error(ctx, "standard output: %m.\n");
- }
- ret = -1;
- }
-
- cfclose(cout);
- cfclose(cerr);
-
- free_colors(ctx->colors);
-
- for (size_t i = 0; i < darray_length(ctx->paths); ++i) {
- free((char *)ctx->paths[i]);
- }
- darray_free(ctx->paths);
-
- free(ctx->argv);
- free(ctx);
- }
-
- return ret;
-}