#include <libmount.h>
#include <blkid.h>
#include <sys/utsname.h>
+#include <stdbool.h>
#include "nls.h"
#include "c.h"
return 0;
}
-static int __attribute__ ((__format__ (__printf__, 2, 3)))
+static int __attribute__ ((__format__ (__printf__, 3, 4)))
verify_ok(struct verify_context *vfy __attribute__((unused)),
+ bool verbose,
const char *fmt, ...)
{
va_list ap;
- if (!(flags & FL_VERBOSE))
+ if (!verbose)
return 0;
va_start(ap, fmt);
return 0;
}
-static int verify_order(struct verify_context *vfy)
+static int verify_order(struct verify_context *vfy, struct findmnt *findmnt)
{
struct libmnt_iter *itr = NULL;
struct libmnt_fs *next;
const char *tgt;
tgt = mnt_fs_get_target(vfy->fs);
- if (tgt && !(flags & FL_NOCACHE))
- tgt = mnt_resolve_target(tgt, cache);
+ if (tgt && !(findmnt->flags & FL_NOCACHE))
+ tgt = mnt_resolve_target(tgt, findmnt->cache);
else if (!tgt)
return 0;
size_t len;
n_tgt = mnt_fs_get_target(next);
- if (n_tgt && !(flags & FL_NOCACHE))
- n_tgt = mnt_resolve_target(n_tgt, cache);
+ if (n_tgt && !(findmnt->flags & FL_NOCACHE))
+ n_tgt = mnt_resolve_target(n_tgt, findmnt->cache);
else if (!n_tgt)
continue;
len = strlen(n_tgt);
return 0;
}
-static int verify_target(struct verify_context *vfy)
+static int verify_target(struct verify_context *vfy, struct findmnt *findmnt)
{
const char *tgt = mnt_fs_get_target(vfy->fs);
struct stat sb;
if (!tgt)
return verify_err(vfy, _("undefined target (fs_file)"));
- if (!(flags & FL_NOCACHE)) {
- const char *cn = mnt_resolve_target(tgt, cache);
+ if (!(findmnt->flags & FL_NOCACHE)) {
+ const char *cn = mnt_resolve_target(tgt, findmnt->cache);
if (!cn)
return -ENOMEM;
if (strcmp(cn, tgt) != 0)
&& mnt_fs_get_option(vfy->fs, "bind", NULL, NULL) == 1) {
verify_err(vfy, _("target is not a directory"));
} else
- verify_ok(vfy, _("target exists"));
+ verify_ok(vfy, findmnt->flags & FL_VERBOSE, _("target exists"));
return 0;
}
static char *verify_tag(struct verify_context *vfy, const char *name,
- const char *value)
+ const char *value, struct findmnt *findmnt)
{
char *src = NULL;
- if (!(flags & FL_NOCACHE))
- src = mnt_resolve_tag(name, value, cache);
+ if (!(findmnt->flags & FL_NOCACHE))
+ src = mnt_resolve_tag(name, value, findmnt->cache);
if (!src) {
if (mnt_fs_get_option(vfy->fs, "noauto", NULL, NULL) == 1)
else
verify_warn(vfy, _("unreachable: %s=%s"), name, value);
} else
- verify_ok(vfy, _("%s=%s translated to %s"), name, value, src);
+ verify_ok(vfy, findmnt->flags & FL_VERBOSE, _("%s=%s translated to %s"), name, value, src);
return src;
}
* interpret unreachable source as error. The exception is only
* NAME=value, this has to be convertible to device name.
*/
-static int verify_source(struct verify_context *vfy)
+static int verify_source(struct verify_context *vfy, struct findmnt *findmnt)
{
const char *src = mnt_fs_get_srcpath(vfy->fs);
char *t = NULL, *v = NULL;
if (mnt_fs_get_tag(vfy->fs, &tag, &val) != 0)
return verify_err(vfy, _("undefined source (fs_spec)"));
- src = verify_tag(vfy, tag, val);
+ src = verify_tag(vfy, tag, val, findmnt);
if (!src)
goto done;
/* source is path */
if (mnt_fs_is_pseudofs(vfy->fs) || mnt_fs_is_netfs(vfy->fs))
- verify_ok(vfy, _("do not check %s source (pseudo/net)"), src);
+ verify_ok(vfy, findmnt->flags & FL_VERBOSE, _("do not check %s source (pseudo/net)"), src);
else if (stat(src, &sb) != 0)
verify_warn(vfy, _("unreachable source: %s: %m"), src);
else if (!S_ISBLK(sb.st_mode) && !isbind)
verify_warn(vfy, _("source %s is not a block device"), src);
else
- verify_ok(vfy, _("source %s exists"), src);
+ verify_ok(vfy, findmnt->flags & FL_VERBOSE, _("source %s exists"), src);
done:
free(t);
free(v);
return rc;
}
-static int verify_options(struct verify_context *vfy)
+static int verify_options(struct verify_context *vfy, bool verbose)
{
const char *opts;
opts = mnt_fs_get_vfs_options(vfy->fs);
if (opts)
- verify_ok(vfy, _("VFS options: %s"), opts);
+ verify_ok(vfy, verbose, _("VFS options: %s"), opts);
opts = mnt_fs_get_fs_options(vfy->fs);
if (opts)
- verify_ok(vfy, _("FS options: %s"), opts);
+ verify_ok(vfy, verbose, _("FS options: %s"), opts);
opts = mnt_fs_get_user_options(vfy->fs);
if (opts)
- verify_ok(vfy, _("userspace options: %s"), opts);
+ verify_ok(vfy, verbose, _("userspace options: %s"), opts);
return 0;
}
return rc;
}
-static int verify_fstype(struct verify_context *vfy)
+static int verify_fstype(struct verify_context *vfy, struct findmnt *findmnt)
{
- char *src = mnt_resolve_spec(mnt_fs_get_source(vfy->fs), cache);
+ char *src = mnt_resolve_spec(mnt_fs_get_source(vfy->fs), findmnt->cache);
char *realtype = NULL;
const char *type;
int ambi = 0, isauto = 0, isswap = 0;
return 0;
if (mnt_fs_is_pseudofs(vfy->fs) || mnt_fs_is_netfs(vfy->fs)) {
- verify_ok(vfy, _("do not check %s FS type (pseudo/net)"), src);
+ verify_ok(vfy, findmnt->flags & FL_VERBOSE, _("do not check %s FS type (pseudo/net)"), src);
goto done;
}
}
errno = 0;
- realtype = mnt_get_fstype(src, &ambi, cache);
+ realtype = mnt_get_fstype(src, &ambi, findmnt->cache);
if (!realtype) {
const char *reson = errno ? strerror(errno) : _("reason unknown");
goto done;
}
- verify_ok(vfy, _("FS type is %s"), realtype);
+ verify_ok(vfy, findmnt->flags & FL_VERBOSE, _("FS type is %s"), realtype);
}
done:
- if (!cache) {
+ if (!findmnt->cache) {
free(src);
free(realtype);
}
return 0;
}
-static int verify_filesystem(struct verify_context *vfy)
+static int verify_filesystem(struct verify_context *vfy, struct findmnt *findmnt)
{
int rc = 0;
if (mnt_fs_is_swaparea(vfy->fs))
rc = verify_swaparea(vfy);
else {
- rc = verify_target(vfy);
+ rc = verify_target(vfy, findmnt);
if (!rc)
- rc = verify_options(vfy);
+ rc = verify_options(vfy, findmnt->flags & FL_VERBOSE);
}
if (!rc)
- rc = verify_source(vfy);
+ rc = verify_source(vfy, findmnt);
if (!rc)
- rc = verify_fstype(vfy);
+ rc = verify_fstype(vfy, findmnt);
if (!rc)
rc = verify_passno(vfy); /* depends on verify_fstype() */
return rc;
}
-int verify_table(struct libmnt_table *tb)
+int verify_table(struct libmnt_table *tb, struct findmnt *findmnt)
{
struct verify_context vfy = { .nerrors = 0 };
struct libmnt_iter *itr;
int rc = 0; /* overall return code (alloc errors, etc.) */
- int check_order = is_listall_mode();
+ int check_order = is_listall_mode(findmnt->flags);
static int has_read_fs = 0;
itr = mnt_new_iter(MNT_ITER_FORWARD);
has_read_fs = 1;
}
- while (rc == 0 && (vfy.fs = get_next_fs(tb, itr))) {
+ while (rc == 0 && (vfy.fs = get_next_fs(tb, itr, findmnt))) {
vfy.target_printed = 0;
vfy.no_fsck = 0;
if (check_order)
- rc = verify_order(&vfy);
+ rc = verify_order(&vfy, findmnt);
if (!rc)
- rc = verify_filesystem(&vfy);
+ rc = verify_filesystem(&vfy, findmnt);
- if (flags & FL_FIRSTONLY)
+ if (findmnt->flags & FL_FIRSTONLY)
break;
- flags |= FL_NOSWAPMATCH;
+ findmnt->flags |= FL_NOSWAPMATCH;
}
#ifdef USE_SYSTEMD
mnt_free_iter(itr);
/* summary */
- if (vfy.nerrors || parse_nerrors || vfy.nwarnings) {
+ if (vfy.nerrors || findmnt->parse_nerrors || vfy.nwarnings) {
fputc('\n', stderr);
- fprintf(stderr, P_("%d parse error", "%d parse errors", parse_nerrors), parse_nerrors);
+ fprintf(stderr, P_("%d parse error", "%d parse errors", findmnt->parse_nerrors), findmnt->parse_nerrors);
fprintf(stderr, P_(", %d error", ", %d errors", vfy.nerrors), vfy.nerrors);
fprintf(stderr, P_(", %d warning", ", %d warnings", vfy.nwarnings), vfy.nwarnings);
fputc('\n', stderr);
free_proc_filesystems(&vfy);
- return rc != 0 ? rc : vfy.nerrors + parse_nerrors;
+ return rc != 0 ? rc : vfy.nerrors + findmnt->parse_nerrors;
}
static int actions[FINDMNT_NACTIONS];
static int nactions;
-/* global (accessed from findmnt-verify.c too) */
-unsigned int flags;
-int parse_nerrors;
-struct libmnt_cache *cache;
-
static blkid_cache blk_cache;
#ifdef HAVE_LIBUDEV
* source match means COL_SOURCE *or* COL_MAJMIN, depends on
* data format.
*/
-static void set_source_match(const char *data)
+static void set_source_match(const char *data, struct findmnt *findmnt)
{
int maj, min;
*devno = makedev(maj, min);
set_match(COL_MAJMIN, data);
set_match_data(COL_MAJMIN, (void *) devno);
- flags |= FL_NOSWAPMATCH;
+ findmnt->flags |= FL_NOSWAPMATCH;
} else
set_match(COL_SOURCE, data);
}
*
* @tb has to be from kernel (so no fstab or so)!
*/
-static void enable_extra_target_match(struct libmnt_table *tb)
+static void enable_extra_target_match(struct libmnt_table *tb, struct findmnt *findmnt)
{
char *cn = NULL;
const char *tgt = NULL, *mnt = NULL;
* Check if match pattern is mountpoint, if not use the
* real mountpoint.
*/
- if (flags & FL_NOCACHE)
+ if (findmnt->flags & FL_NOCACHE)
tgt = get_match(COL_TARGET);
else {
- tgt = cn = mnt_resolve_path(get_match(COL_TARGET), cache);
+ tgt = cn = mnt_resolve_path(get_match(COL_TARGET), findmnt->cache);
if (!cn)
return;
}
if (mnt && strcmp(mnt, tgt) != 0)
set_match(COL_TARGET, xstrdup(mnt)); /* replace the current setting */
- if (!cache)
+ if (!findmnt->cache)
free(cn);
}
/*
* "findmnt" without any filter
*/
-int is_listall_mode(void)
+int is_listall_mode(unsigned int flags)
{
if ((flags & FL_DF || flags & FL_REAL || flags & FL_PSEUDO) && !(flags & FL_ALL))
return 0;
*
* ... it works like "mount <devname|TAG=|mountpoint>"
*/
-static int is_mount_compatible_mode(void)
+static int is_mount_compatible_mode(unsigned int flags)
{
if (!get_match(COL_SOURCE))
return 0; /* <devname|TAG=|mountpoint> is required */
#ifndef HAVE_LIBUDEV
__attribute__((__unused__))
#endif
- )
+ , struct findmnt *findmnt)
{
const char *t, *v;
char *res = NULL;
else {
const char *dev = mnt_fs_get_source(fs);
- if (dev && !(flags & FL_NOCACHE))
- dev = mnt_resolve_spec(dev, cache);
+ if (dev && !(findmnt->flags & FL_NOCACHE))
+ dev = mnt_resolve_spec(dev, findmnt->cache);
#ifdef HAVE_LIBUDEV
if (dev)
res = get_tag_from_udev(dev, col);
#endif
if (!res) {
- res = mnt_cache_find_tag_value(cache, dev, tagname);
- if (res && cache)
+ res = mnt_cache_find_tag_value(findmnt->cache, dev, tagname);
+ if (res && findmnt->cache)
/* don't return pointer to cache */
res = xstrdup(res);
}
return res;
}
-static char *get_vfs_attr(struct libmnt_fs *fs, int sizetype)
+static char *get_vfs_attr(struct libmnt_fs *fs, int sizetype, unsigned int flags)
{
struct statvfs buf;
uint64_t vfs_attr = 0;
/* reads FS data from libmount
*/
-static char *get_data(struct libmnt_fs *fs, int num, size_t *datasiz)
+static char *get_data(struct libmnt_fs *fs, int num, size_t *datasiz, struct findmnt *findmnt)
{
char *str = NULL;
int col_id = get_column_id(num);
switch (col_id) {
case COL_SOURCES:
/* print all devices with the same tag (LABEL, UUID) */
- str = get_data_col_sources(fs, flags & FL_EVALUATE, datasiz);
+ str = get_data_col_sources(fs, findmnt->flags & FL_EVALUATE, datasiz);
if (str)
break;
const char *spec = mnt_fs_get_srcpath(fs);
char *cn = NULL;
- if (spec && (flags & FL_CANONICALIZE))
- spec = cn = mnt_resolve_path(spec, cache);
+ if (spec && (findmnt->flags & FL_CANONICALIZE))
+ spec = cn = mnt_resolve_path(spec, findmnt->cache);
if (!spec) {
spec = mnt_fs_get_source(fs);
- if (spec && (flags & FL_EVALUATE))
- spec = cn = mnt_resolve_spec(spec, cache);
+ if (spec && (findmnt->flags & FL_EVALUATE))
+ spec = cn = mnt_resolve_spec(spec, findmnt->cache);
}
- if (root && spec && !(flags & FL_NOFSROOT) && strcmp(root, "/") != 0)
+ if (root && spec && !(findmnt->flags & FL_NOFSROOT) && strcmp(root, "/") != 0)
xasprintf(&str, "%s[%s]", spec, root);
else if (spec)
str = xstrdup(spec);
- if (!cache)
+ if (!findmnt->cache)
free(cn);
break;
}
str = xstrdup(mnt_fs_get_options(fs));
break;
case COL_VFS_OPTIONS:
- if (flags & FL_VFS_ALL)
+ if (findmnt->flags & FL_VFS_ALL)
str = mnt_fs_get_vfs_options_all(fs);
else if (mnt_fs_get_vfs_options(fs))
str = xstrdup(mnt_fs_get_vfs_options(fs));
str = xstrdup(mnt_fs_get_optional_fields(fs));
break;
case COL_UUID:
- str = get_tag(fs, "UUID", col_id);
+ str = get_tag(fs, "UUID", col_id, findmnt);
break;
case COL_PARTUUID:
- str = get_tag(fs, "PARTUUID", col_id);
+ str = get_tag(fs, "PARTUUID", col_id, findmnt);
break;
case COL_LABEL:
- str = get_tag(fs, "LABEL", col_id);
+ str = get_tag(fs, "LABEL", col_id, findmnt);
break;
case COL_PARTLABEL:
- str = get_tag(fs, "PARTLABEL", col_id);
+ str = get_tag(fs, "PARTLABEL", col_id, findmnt);
break;
case COL_MAJMIN:
if (!devno)
break;
- if ((flags & FL_RAW) || (flags & FL_EXPORT) || (flags & FL_JSON))
+ if ((findmnt->flags & FL_RAW) || (findmnt->flags & FL_EXPORT) || (findmnt->flags & FL_JSON))
xasprintf(&str, "%u:%u", major(devno), minor(devno));
else
xasprintf(&str, "%3u:%-3u", major(devno), minor(devno));
case COL_INO_AVAIL:
case COL_INO_USED:
case COL_INO_USEPERC:
- str = get_vfs_attr(fs, col_id);
+ str = get_vfs_attr(fs, col_id, findmnt->flags);
break;
case COL_FSROOT:
if (mnt_fs_get_root(fs))
struct libmnt_fs *new_fs,
int change,
int num,
- size_t *datasiz)
+ size_t *datasiz,
+ struct findmnt *findmnt)
{
char *str = NULL;
break;
default:
if (new_fs)
- str = get_data(new_fs, num, datasiz);
+ str = get_data(new_fs, num, datasiz, findmnt);
else
- str = get_data(old_fs, num, datasiz);
+ str = get_data(old_fs, num, datasiz, findmnt);
break;
}
return str;
/* adds one line to the output @tab */
static struct libscols_line *add_line(struct libscols_table *table, struct libmnt_fs *fs,
- struct libscols_line *parent)
+ struct libscols_line *parent, struct findmnt *findmnt)
{
size_t i;
struct libscols_line *line = scols_table_new_line(table, parent);
for (i = 0; i < ncolumns; i++) {
size_t datasiz = 0;
- char *data = get_data(fs, i, &datasiz);
+ char *data = get_data(fs, i, &datasiz, findmnt);
if (data)
set_line_data(line, i, data, datasiz);
}
static struct libscols_line *add_tabdiff_line(struct libscols_table *table, struct libmnt_fs *new_fs,
- struct libmnt_fs *old_fs, int change)
+ struct libmnt_fs *old_fs, int change, struct findmnt *findmnt)
{
size_t i;
struct libscols_line *line = scols_table_new_line(table, NULL);
for (i = 0; i < ncolumns; i++) {
size_t datasiz = 0;
- char *data = get_tabdiff_data(old_fs, new_fs, change, i, &datasiz);
+ char *data = get_tabdiff_data(old_fs, new_fs, change, i, &datasiz, findmnt);
if (data)
set_line_data(line, i, data, datasiz);
/* reads filesystems from @tb (libmount) and fillin @table (output table) */
static int create_treenode(struct libscols_table *table, struct libmnt_table *tb,
- struct libmnt_fs *fs, struct libscols_line *parent_line)
+ struct libmnt_fs *fs, struct libscols_line *parent_line, struct findmnt *findmnt)
{
struct libmnt_fs *chld = NULL;
struct libmnt_iter *itr = NULL;
parent_line = NULL;
first = 1;
- } else if ((flags & FL_SUBMOUNTS) && has_line(table, fs))
+ } else if ((findmnt->flags & FL_SUBMOUNTS) && has_line(table, fs))
return 0;
itr = mnt_new_iter(MNT_ITER_FORWARD);
if (!itr)
goto leave;
- if ((flags & FL_SUBMOUNTS) || match_func(fs, NULL)) {
- line = add_line(table, fs, parent_line);
+ if ((findmnt->flags & FL_SUBMOUNTS) || match_func(fs, NULL)) {
+ line = add_line(table, fs, parent_line, findmnt);
if (!line)
goto leave;
} else
* add all children to the output table
*/
while (mnt_table_next_child_fs(tb, itr, fs, &chld) == 0) {
- if (create_treenode(table, tb, chld, line))
+ if (create_treenode(table, tb, chld, line, findmnt))
goto leave;
}
rc = 0;
while (mnt_table_next_fs(tb, itr, &fs) == 0) {
if (!has_line(table, fs) && match_func(fs, NULL))
- create_treenode(table, tb, fs, NULL);
+ create_treenode(table, tb, fs, NULL, findmnt);
}
}
leave:
}
/* error callback */
-static int parser_errcb(struct libmnt_table *tb __attribute__ ((__unused__)),
+static int parser_errcb(struct libmnt_table *tb,
const char *filename, int line)
{
+ struct findmnt *findmnt = mnt_table_get_userdata(tb);
warnx(_("%s: parse error at line %d -- ignored"), filename, line);
- ++parse_nerrors;
+ findmnt->parse_nerrors++;
return 1;
}
/* filter function for libmount (mnt_table_find_next_fs()) */
static int match_func(struct libmnt_fs *fs,
- void *data __attribute__ ((__unused__)))
+ void *data)
{
- int rc = flags & FL_INVERT ? 1 : 0;
+ struct findmnt *findmnt = data;
+ int rc = findmnt->flags & FL_INVERT ? 1 : 0;
const char *m;
void *md;
return rc;
m = get_match(COL_TARGET);
- if (m && !mnt_fs_match_target(fs, m, cache))
+ if (m && !mnt_fs_match_target(fs, m, findmnt->cache))
return rc;
m = get_match(COL_SOURCE);
- if (m && !mnt_fs_match_source(fs, m, cache))
+ if (m && !mnt_fs_match_source(fs, m, findmnt->cache))
return rc;
- if ((flags & FL_DF) && !(flags & FL_ALL)) {
+ if ((findmnt->flags & FL_DF) && !(findmnt->flags & FL_ALL)) {
const char *type = mnt_fs_get_fstype(fs);
if (type && strstr(type, "tmpfs")) /* tmpfs is wanted */
return rc;
}
- if ((flags & FL_REAL) && mnt_fs_is_pseudofs(fs))
+ if ((findmnt->flags & FL_REAL) && mnt_fs_is_pseudofs(fs))
return rc;
- if ((flags & FL_PSEUDO) && !mnt_fs_is_pseudofs(fs))
+ if ((findmnt->flags & FL_PSEUDO) && !mnt_fs_is_pseudofs(fs))
return rc;
- if ((flags & FL_SHADOWED)) {
+ if ((findmnt->flags & FL_SHADOWED)) {
struct libmnt_table *tb = NULL;
mnt_fs_get_table(fs, &tb);
/* iterate over filesystems in @tb */
struct libmnt_fs *get_next_fs(struct libmnt_table *tb,
- struct libmnt_iter *itr)
+ struct libmnt_iter *itr,
+ struct findmnt *findmnt)
{
struct libmnt_fs *fs = NULL;
- if (is_listall_mode()) {
+ if (is_listall_mode(findmnt->flags)) {
/*
* Print whole file
*/
if (mnt_table_next_fs(tb, itr, &fs) != 0)
return NULL;
- } else if (is_mount_compatible_mode()) {
+ } else if (is_mount_compatible_mode(findmnt->flags)) {
/*
* Look up for FS in the same way how mount(8) searches in fstab
*
fs = mnt_table_find_source(tb, get_match(COL_SOURCE),
mnt_iter_get_direction(itr));
- if (!fs && !(flags & FL_NOSWAPMATCH))
+ if (!fs && !(findmnt->flags & FL_NOSWAPMATCH))
fs = mnt_table_find_target(tb, get_match(COL_SOURCE),
mnt_iter_get_direction(itr));
} else {
* findmnt [-l] <spec> [-O <options>] [-t <types>]
*/
again:
- if (mnt_table_find_next_fs(tb, itr, match_func, NULL, &fs) != 0)
+ if (mnt_table_find_next_fs(tb, itr, match_func, findmnt, &fs) != 0)
fs = NULL;
if (!fs &&
- !(flags & FL_NOSWAPMATCH) &&
+ !(findmnt->flags & FL_NOSWAPMATCH) &&
!get_match(COL_TARGET) && get_match(COL_SOURCE)) {
/* swap 'spec' and target. */
* --submounts tree output.
*/
static int add_matching_lines(struct libmnt_table *tb,
- struct libscols_table *table, int direction)
+ struct libscols_table *table, int direction,
+ struct findmnt *findmnt)
{
struct libmnt_iter *itr;
struct libmnt_fs *fs;
goto done;
}
- while((fs = get_next_fs(tb, itr))) {
- if ((flags & FL_TREE) || (flags & FL_SUBMOUNTS))
- rc = create_treenode(table, tb, fs, NULL);
+ while((fs = get_next_fs(tb, itr, findmnt))) {
+ if ((findmnt->flags & FL_TREE) || (findmnt->flags & FL_SUBMOUNTS))
+ rc = create_treenode(table, tb, fs, NULL, findmnt);
else
- rc = !add_line(table, fs, NULL);
+ rc = !add_line(table, fs, NULL, findmnt);
if (rc)
goto done;
nlines++;
- if (flags & FL_FIRSTONLY)
+ if (findmnt->flags & FL_FIRSTONLY)
break;
- flags |= FL_NOSWAPMATCH;
+ findmnt->flags |= FL_NOSWAPMATCH;
}
if (nlines)
return rc;
}
-static int poll_match(struct libmnt_fs *fs)
+static int poll_match(struct libmnt_fs *fs, struct findmnt *findmnt)
{
- int rc = match_func(fs, NULL);
+ int rc = match_func(fs, findmnt);
- if (rc == 0 && !(flags & FL_NOSWAPMATCH) &&
+ if (rc == 0 && !(findmnt->flags & FL_NOSWAPMATCH) &&
get_match(COL_SOURCE) && !get_match(COL_TARGET)) {
/*
* findmnt --poll /foo
set_match(COL_TARGET, str); /* swap */
set_match(COL_SOURCE, NULL);
- rc = match_func(fs, NULL);
+ rc = match_func(fs, findmnt);
set_match(COL_TARGET, NULL); /* restore */
set_match(COL_SOURCE, str);
}
static int poll_table(struct libmnt_table *tb, const char *tabfile,
- int timeout, struct libscols_table *table, int direction)
+ int timeout, struct libscols_table *table, int direction, struct findmnt *findmnt)
{
FILE *f = NULL;
int rc = -1;
if (!has_poll_action(change))
continue;
- if (!poll_match(new ? new : old))
+ if (!poll_match(new ? new : old, findmnt))
continue;
count++;
- rc = !add_tabdiff_line(table, new, old, change);
+ rc = !add_tabdiff_line(table, new, old, change, findmnt);
if (rc)
goto done;
- if (flags & FL_FIRSTONLY)
+ if (findmnt->flags & FL_FIRSTONLY)
break;
}
scols_table_remove_lines(table);
mnt_reset_table(tb_new);
- if (count && (flags & FL_FIRSTONLY))
+ if (count && (findmnt->flags & FL_FIRSTONLY))
break;
}
}
static int uniq_fs_target_cmp(
- struct libmnt_table *tb __attribute__((__unused__)),
+ struct libmnt_table *tb,
struct libmnt_fs *a,
struct libmnt_fs *b)
{
- return !mnt_fs_match_target(a, mnt_fs_get_target(b), cache);
+ struct findmnt *findmnt = mnt_table_get_userdata(tb);
+ return !mnt_fs_match_target(a, mnt_fs_get_target(b), findmnt->cache);
}
-static int get_column_json_type(int id, int scols_flags, int *multi)
+static int get_column_json_type(int id, int scols_flags, int *multi, unsigned int findmnt_flags)
{
switch (id) {
case COL_SIZE:
case COL_USED:
if (multi)
*multi = 1;
- if (!(flags & FL_BYTES))
+ if (!(findmnt_flags & FL_BYTES))
break;
/* fallthrough */
case COL_ID:
exit(EXIT_SUCCESS);
}
-static void __attribute__((__noreturn__)) list_colunms(void)
+static void __attribute__((__noreturn__)) list_colunms(struct findmnt *findmnt)
{
size_t i;
struct libscols_table *tb = xcolumn_list_table_new("findmnt-columns", stdout,
- flags & FL_RAW,
- flags & FL_JSON);
+ findmnt->flags & FL_RAW,
+ findmnt->flags & FL_JSON);
for (i = 0; i < ARRAY_SIZE(infos); i++) {
const struct colinfo *ci = &infos[i];
int multi = 0;
- int json = get_column_json_type(i, ci->flags, &multi);
+ int json = get_column_json_type(i, ci->flags, &multi,
+ findmnt->flags);
xcolumn_list_table_append_line(tb, ci->name,
multi ? -1 : json,
int main(int argc, char *argv[])
{
+ struct findmnt findmnt = {
+ .cache = NULL,
+ .flags = 0,
+ .parse_nerrors = 0,
+ };
struct libmnt_table *tb = NULL;
char **tabfiles = NULL;
int direction = MNT_ITER_FORWARD;
close_stdout_atexit();
/* default output format */
- flags |= FL_TREE;
+ findmnt.flags |= FL_TREE;
while ((c = getopt_long(argc, argv,
"AabCcDd:ehIiJfF:o:O:p::PklmM:nN:rst:uvRS:T:Uw:VxyH",
switch(c) {
case 'A':
- flags |= FL_ALL;
+ findmnt.flags |= FL_ALL;
break;
case 'a':
- flags |= FL_ASCII;
+ findmnt.flags |= FL_ASCII;
break;
case 'b':
- flags |= FL_BYTES;
+ findmnt.flags |= FL_BYTES;
break;
case 'C':
- flags |= FL_NOCACHE;
+ findmnt.flags |= FL_NOCACHE;
break;
case 'c':
- flags |= FL_CANONICALIZE;
+ findmnt.flags |= FL_CANONICALIZE;
break;
case 'D':
- flags &= ~FL_TREE;
- flags |= FL_DF;
+ findmnt.flags &= ~FL_TREE;
+ findmnt.flags |= FL_DF;
break;
case 'd':
if (!strcmp(optarg, "forward"))
_("unknown direction '%s'"), optarg);
break;
case 'e':
- flags |= FL_EVALUATE;
+ findmnt.flags |= FL_EVALUATE;
break;
case 'I':
- flags &= ~FL_TREE;
- flags |= (FL_DF_INODES | FL_DF);
+ findmnt.flags &= ~FL_TREE;
+ findmnt.flags |= (FL_DF_INODES | FL_DF);
break;
case 'i':
- flags |= FL_INVERT;
+ findmnt.flags |= FL_INVERT;
break;
case 'J':
- flags |= FL_JSON;
+ findmnt.flags |= FL_JSON;
break;
case 'f':
- flags |= FL_FIRSTONLY;
+ findmnt.flags |= FL_FIRSTONLY;
break;
case 'F':
tabfiles = append_tabfile(tabfiles, &ntabfiles, optarg);
if (nactions < 0)
exit(EXIT_FAILURE);
}
- flags |= FL_POLL;
- flags &= ~FL_TREE;
+ findmnt.flags |= FL_POLL;
+ findmnt.flags &= ~FL_TREE;
break;
case 'P':
- flags |= FL_EXPORT;
- flags &= ~FL_TREE;
+ findmnt.flags |= FL_EXPORT;
+ findmnt.flags &= ~FL_TREE;
break;
case 'm': /* mtab */
tabtype = TABTYPE_MTAB;
- flags &= ~FL_TREE;
+ findmnt.flags &= ~FL_TREE;
break;
case 's': /* fstab */
tabtype = TABTYPE_FSTAB;
- flags &= ~FL_TREE;
+ findmnt.flags &= ~FL_TREE;
break;
case 'k': /* kernel (mountinfo) */
tabtype = TABTYPE_KERNEL;
set_match(COL_FSTYPE, optarg);
break;
case 'r':
- flags &= ~FL_TREE; /* disable the default */
- flags |= FL_RAW; /* enable raw */
+ findmnt.flags &= ~FL_TREE; /* disable the default */
+ findmnt.flags |= FL_RAW; /* enable raw */
break;
case 'l':
- flags &= ~FL_TREE; /* disable the default */
+ findmnt.flags &= ~FL_TREE; /* disable the default */
break;
case 'n':
- flags |= FL_NOHEADINGS;
+ findmnt.flags |= FL_NOHEADINGS;
break;
case 'N':
tabtype = TABTYPE_KERNEL;
_("invalid TID argument")));
break;
case 'v':
- flags |= FL_NOFSROOT;
+ findmnt.flags |= FL_NOFSROOT;
break;
case 'R':
- flags |= FL_SUBMOUNTS;
+ findmnt.flags |= FL_SUBMOUNTS;
break;
case 'S':
- set_source_match(optarg);
- flags |= FL_NOSWAPMATCH;
+ set_source_match(optarg, &findmnt);
+ findmnt.flags |= FL_NOSWAPMATCH;
break;
case 'M':
- flags |= FL_STRICTTARGET;
+ findmnt.flags |= FL_STRICTTARGET;
/* fallthrough */
case 'T':
set_match(COL_TARGET, optarg);
- flags |= FL_NOSWAPMATCH;
+ findmnt.flags |= FL_NOSWAPMATCH;
break;
case 'U':
- flags |= FL_UNIQ;
+ findmnt.flags |= FL_UNIQ;
break;
case 'w':
timeout = strtos32_or_err(optarg, _("invalid timeout argument"));
verify = 1;
break;
case 'y':
- flags |= FL_SHELLVAR;
+ findmnt.flags |= FL_SHELLVAR;
break;
case FINDMNT_OPT_VERBOSE:
- flags |= FL_VERBOSE;
+ findmnt.flags |= FL_VERBOSE;
break;
case FINDMNT_OPT_TREE:
force_tree = 1;
break;
case FINDMNT_OPT_PSEUDO:
- flags |= FL_PSEUDO;
+ findmnt.flags |= FL_PSEUDO;
break;
case FINDMNT_OPT_REAL:
- flags |= FL_REAL;
+ findmnt.flags |= FL_REAL;
break;
case FINDMNT_OPT_VFS_ALL:
- flags |= FL_VFS_ALL;
+ findmnt.flags |= FL_VFS_ALL;
break;
case FINDMNT_OPT_SHADOWED:
- flags |= FL_SHADOWED;
+ findmnt.flags |= FL_SHADOWED;
break;
case 'H':
}
if (collist)
- list_colunms(); /* print end exit */
+ list_colunms(&findmnt); /* print end exit */
- if (!ncolumns && (flags & FL_DF)) {
+ if (!ncolumns && (findmnt.flags & FL_DF)) {
add_column(columns, ncolumns++, COL_SOURCE);
add_column(columns, ncolumns++, COL_FSTYPE);
- if (flags & FL_DF_INODES) {
+ if (findmnt.flags & FL_DF_INODES) {
add_column(columns, ncolumns++, COL_INO_TOTAL);
add_column(columns, ncolumns++, COL_INO_USED);
add_column(columns, ncolumns++, COL_INO_AVAIL);
/* default columns */
if (!ncolumns) {
- if (flags & FL_POLL)
+ if (findmnt.flags & FL_POLL)
add_column(columns, ncolumns++, COL_ACTION);
add_column(columns, ncolumns++, COL_TARGET);
if (!tabtype)
tabtype = verify ? TABTYPE_FSTAB : TABTYPE_KERNEL;
- if ((flags & FL_POLL) && ntabfiles > 1)
+ if ((findmnt.flags & FL_POLL) && ntabfiles > 1)
errx(EXIT_FAILURE, _("--poll accepts only one file, but more specified by --tab-file"));
if (optind < argc && (get_match(COL_SOURCE) || get_match(COL_TARGET)))
"with command line element that is not an option"));
if (optind < argc)
- set_source_match(argv[optind++]); /* dev/tag/mountpoint/maj:min */
+ set_source_match(argv[optind++], &findmnt); /* dev/tag/mountpoint/maj:min */
if (optind < argc)
set_match(COL_TARGET, argv[optind++]); /* mountpoint */
- if ((flags & FL_SUBMOUNTS) && is_listall_mode())
+ if ((findmnt.flags & FL_SUBMOUNTS) && is_listall_mode(findmnt.flags))
/* don't care about submounts if list all mounts */
- flags &= ~FL_SUBMOUNTS;
+ findmnt.flags &= ~FL_SUBMOUNTS;
- if (!(flags & FL_SUBMOUNTS) && ((flags & FL_FIRSTONLY)
+ if (!(findmnt.flags & FL_SUBMOUNTS) && ((findmnt.flags & FL_FIRSTONLY)
|| get_match(COL_TARGET)
|| get_match(COL_SOURCE)
|| get_match(COL_MAJMIN)))
- flags &= ~FL_TREE;
+ findmnt.flags &= ~FL_TREE;
- if (!(flags & FL_NOSWAPMATCH) &&
+ if (!(findmnt.flags & FL_NOSWAPMATCH) &&
!get_match(COL_TARGET) && get_match(COL_SOURCE)) {
/*
* Check if we can swap source and target, it's
if (!strncmp(x, "LABEL=", 6) || !strncmp(x, "UUID=", 5) ||
!strncmp(x, "PARTLABEL=", 10) || !strncmp(x, "PARTUUID=", 9))
- flags |= FL_NOSWAPMATCH;
+ findmnt.flags |= FL_NOSWAPMATCH;
}
/*
tb = parse_tabfiles(tabfiles, ntabfiles, tabtype);
if (!tb)
goto leave;
+ mnt_table_set_userdata(tb, &findmnt);
if (tabtype == TABTYPE_MTAB && tab_is_kernel(tb))
tabtype = TABTYPE_KERNEL;
istree = tab_is_tree(tb);
if (istree && force_tree)
- flags |= FL_TREE;
+ findmnt.flags |= FL_TREE;
- if ((flags & FL_TREE) && (ntabfiles > 1 || !istree))
- flags &= ~FL_TREE;
+ if ((findmnt.flags & FL_TREE) && (ntabfiles > 1 || !istree))
+ findmnt.flags &= ~FL_TREE;
- if (!(flags & FL_NOCACHE)) {
- cache = mnt_new_cache();
- if (!cache) {
+ if (!(findmnt.flags & FL_NOCACHE)) {
+ findmnt.cache = mnt_new_cache();
+ if (!findmnt.cache) {
warn(_("failed to initialize libmount cache"));
goto leave;
}
- mnt_table_set_cache(tb, cache);
+ mnt_table_set_cache(tb, findmnt.cache);
if (tabtype != TABTYPE_KERNEL)
- cache_set_targets(cache);
+ cache_set_targets(findmnt.cache);
}
- if (flags & FL_UNIQ)
+ if (findmnt.flags & FL_UNIQ)
mnt_table_uniq_fs(tb, MNT_UNIQ_KEEPTREE, uniq_fs_target_cmp);
if (verify) {
- rc = verify_table(tb);
+ rc = verify_table(tb, &findmnt);
goto leave;
}
warn(_("failed to allocate output table"));
goto leave;
}
- scols_table_enable_raw(table, !!(flags & FL_RAW));
- scols_table_enable_export(table, !!(flags & FL_EXPORT));
- scols_table_enable_shellvar(table, !!(flags & FL_SHELLVAR));
- scols_table_enable_json(table, !!(flags & FL_JSON));
- scols_table_enable_ascii(table, !!(flags & FL_ASCII));
- scols_table_enable_noheadings(table, !!(flags & FL_NOHEADINGS));
-
- if (flags & FL_JSON)
+ scols_table_enable_raw(table, !!(findmnt.flags & FL_RAW));
+ scols_table_enable_export(table, !!(findmnt.flags & FL_EXPORT));
+ scols_table_enable_shellvar(table, !!(findmnt.flags & FL_SHELLVAR));
+ scols_table_enable_json(table, !!(findmnt.flags & FL_JSON));
+ scols_table_enable_ascii(table, !!(findmnt.flags & FL_ASCII));
+ scols_table_enable_noheadings(table, !!(findmnt.flags & FL_NOHEADINGS));
+
+ if (findmnt.flags & FL_JSON)
scols_table_set_name(table, "filesystems");
for (i = 0; i < ncolumns; i++) {
int fl = get_column_flags(i);
int id = get_column_id(i);
- if (!(flags & FL_TREE))
+ if (!(findmnt.flags & FL_TREE))
fl &= ~SCOLS_FL_TREE;
- if (!(flags & FL_POLL) && is_tabdiff_column(id)) {
+ if (!(findmnt.flags & FL_POLL) && is_tabdiff_column(id)) {
warnx(_("%s column is requested, but --poll "
"is not enabled"), get_column_name(i));
goto leave;
NULL,
scols_wrapzero_nextchunk,
NULL);
- if (flags & FL_JSON)
- scols_column_set_json_type(cl, get_column_json_type(id, fl, NULL));
+ if (findmnt.flags & FL_JSON)
+ scols_column_set_json_type(cl, get_column_json_type(id, fl, NULL,
+ findmnt.flags));
}
/*
* Fill in data to the output table
*/
- if (flags & FL_POLL) {
+ if (findmnt.flags & FL_POLL) {
/* poll mode (accept the first tabfile only) */
- rc = poll_table(tb, tabfiles ? *tabfiles : _PATH_PROC_MOUNTINFO, timeout, table, direction);
+ rc = poll_table(tb, tabfiles ? *tabfiles : _PATH_PROC_MOUNTINFO, timeout, table, direction, &findmnt);
- } else if ((flags & FL_TREE) && !(flags & FL_SUBMOUNTS)) {
+ } else if ((findmnt.flags & FL_TREE) && !(findmnt.flags & FL_SUBMOUNTS)) {
/* whole tree */
- rc = create_treenode(table, tb, NULL, NULL);
+ rc = create_treenode(table, tb, NULL, NULL, &findmnt);
} else {
/* whole list of sub-tree */
- rc = add_matching_lines(tb, table, direction);
+ rc = add_matching_lines(tb, table, direction, &findmnt);
if (rc != 0
&& tabtype == TABTYPE_KERNEL
- && (flags & FL_NOSWAPMATCH)
- && !(flags & FL_STRICTTARGET)
+ && (findmnt.flags & FL_NOSWAPMATCH)
+ && !(findmnt.flags & FL_STRICTTARGET)
&& get_match(COL_TARGET)) {
/*
* Found nothing, maybe the --target is regular file,
* try it again with extra functionality for target
* match
*/
- enable_extra_target_match(tb);
- rc = add_matching_lines(tb, table, direction);
+ enable_extra_target_match(tb, &findmnt);
+ rc = add_matching_lines(tb, table, direction, &findmnt);
}
}
/*
* Print the output table for non-poll modes
*/
- if (!rc && !(flags & FL_POLL))
+ if (!rc && !(findmnt.flags & FL_POLL))
scols_print_table(table);
leave:
scols_unref_table(table);
mnt_unref_table(tb);
- mnt_unref_cache(cache);
+ mnt_unref_cache(findmnt.cache);
free(tabfiles);
#ifdef HAVE_LIBUDEV