summaryrefslogtreecommitdiffstats
path: root/misc-utils/findmnt.c
diff options
context:
space:
mode:
authorKarel Zak2010-04-06 16:16:27 +0200
committerKarel Zak2010-06-03 15:20:12 +0200
commitfdedb45e3105a2d1cb6baf41b792d955ccd7a0bb (patch)
tree7334a34f8d4c89eb468e384da6e29099f8568ad6 /misc-utils/findmnt.c
parentlib: add tt.c (Tree and Table output) (diff)
downloadkernel-qcow2-util-linux-fdedb45e3105a2d1cb6baf41b792d955ccd7a0bb.tar.gz
kernel-qcow2-util-linux-fdedb45e3105a2d1cb6baf41b792d955ccd7a0bb.tar.xz
kernel-qcow2-util-linux-fdedb45e3105a2d1cb6baf41b792d955ccd7a0bb.zip
findmnt: rewrite to use lib/tt.c
Signed-off-by: Karel Zak <kzak@redhat.com>
Diffstat (limited to 'misc-utils/findmnt.c')
-rw-r--r--misc-utils/findmnt.c713
1 files changed, 166 insertions, 547 deletions
diff --git a/misc-utils/findmnt.c b/misc-utils/findmnt.c
index 0fdb16c95..70678235f 100644
--- a/misc-utils/findmnt.c
+++ b/misc-utils/findmnt.c
@@ -18,7 +18,6 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
@@ -33,14 +32,14 @@
#ifdef HAVE_SYS_IOCTL_H
#include <sys/ioctl.h>
#endif
-#include <mount.h>
-
#include <assert.h>
+#include <mount.h>
+
#include "pathnames.h"
#include "nls.h"
-#include "widechar.h"
#include "c.h"
+#include "tt.h"
/* flags */
enum {
@@ -48,10 +47,7 @@ enum {
FL_CANONICALIZE = (1 << 2),
FL_FIRSTONLY = (1 << 3),
FL_INVERT = (1 << 4),
- FL_NOHEADINGS = (1 << 5),
FL_NOSWAPMATCH = (1 << 6),
- FL_TREE = (1 << 7),
- FL_RAW = (1 << 8)
};
/* column IDs */
@@ -66,101 +62,42 @@ enum {
__NCOLUMNS
};
-struct treenode {
- mnt_fs *fs; /* filesystem */
-
- struct treenode *parent;
- struct treenode *first; /* first child */
- struct treenode *last; /* last child */
-
- struct treenode *next; /* next node in the same level */
-};
-
/* column names */
struct colinfo {
const char *name; /* header */
double whint; /* width hint (N < 1 is in percent of termwidth) */
- int wrap; /* boolean (FALSE = truncate the column) */
-
- int width; /* real column width */
+ int truncate; /* boolean */
const char *match; /* pattern for match_func() */
};
/* columns descriptions */
struct colinfo infos[__NCOLUMNS] = {
- [COL_SOURCE] = { "SOURCE", 0.25, TRUE },
- [COL_TARGET] = { "TARGET", 0.30, TRUE },
- [COL_FSTYPE] = { "FSTYPE", 0.10, FALSE },
- [COL_OPTIONS] = { "OPTIONS", 0.10, FALSE },
- [COL_LABEL] = { "LABEL", 0.10, TRUE },
- [COL_UUID] = { "UUID", 36, TRUE },
+ [COL_SOURCE] = { "SOURCE", 0.25, FALSE },
+ [COL_TARGET] = { "TARGET", 0.30, FALSE },
+ [COL_FSTYPE] = { "FSTYPE", 0.10, TRUE },
+ [COL_OPTIONS] = { "OPTIONS", 0.10, TRUE },
+ [COL_LABEL] = { "LABEL", 0.10, FALSE },
+ [COL_UUID] = { "UUID", 36, FALSE },
};
-struct treesym {
- const char *branch;
- const char *vert;
- const char *right;
-};
-const struct treesym ascii_tree_symbols = {
- .branch = "|-",
- .vert = "| ",
- .right = "`-",
-};
-
-#ifdef HAVE_WIDECHAR
-
-#define mbs_width(_s) mbstowcs(NULL, _s, 0)
-
-#define UTF_V "\342\224\202" /* U+2502, Vertical line drawing char */
-#define UTF_VR "\342\224\234" /* U+251C, Vertical and right */
-#define UTF_H "\342\224\200" /* U+2500, Horizontal */
-#define UTF_UR "\342\224\224" /* U+2514, Up and right */
-
-const struct treesym utf_tree_symbols = {
- .branch = UTF_VR UTF_H,
- .vert = UTF_V " ",
- .right = UTF_UR UTF_H,
-};
-
-const struct treesym *tree_symbols = &utf_tree_symbols;
-
-#else /* !HAVE_WIDECHAR */
-
-# define mbs_width strlen(_s)
-const struct treesym *tree_symbols = &ascii_tree_symbols;
-
-#endif /* !HAVE_WIDECHAR */
-
/* global flags */
int flags;
-/* array IDs of with enabled columns */
+/* array with IDs of enabled columns */
int columns[__NCOLUMNS];
int ncolumns;
-int termwidth; /* terminal width */
-char *treebuf; /* buffer for target column in tree mode */
-
/* libmount cache */
mnt_cache *cache;
-
-static inline int is_last_column(int num)
-{
- return num + 1 == ncolumns;
-}
-
static inline int get_column_id(int num)
{
- int id;
assert(num < ncolumns);
-
- id = columns[num];
- assert(id < __NCOLUMNS);
- return id;
+ assert(columns[num] < __NCOLUMNS);
+ return columns[num];
}
-static inline struct colinfo *get_column_desc(int num)
+static inline struct colinfo *get_column_info(int num)
{
return &infos[ get_column_id(num) ];
}
@@ -173,27 +110,17 @@ static inline const char *column_id_to_name(int id)
static inline const char *get_column_name(int num)
{
- return get_column_desc(num)->name;
+ return get_column_info(num)->name;
}
static inline float get_column_whint(int num)
{
- return get_column_desc(num)->whint;
+ return get_column_info(num)->whint;
}
-static inline int get_column_width(int num)
+static inline int get_column_truncate(int num)
{
- return get_column_desc(num)->width;
-}
-
-static inline void set_column_width(int num, int width)
-{
- get_column_desc(num)->width = width;
-}
-
-static inline int get_column_wrap(int num)
-{
- return get_column_desc(num)->wrap;
+ return get_column_info(num)->truncate;
}
static inline const char *get_match(int id)
@@ -236,12 +163,12 @@ static inline int is_mount_compatible_mode(void)
return 1; /* ok */
}
-static void set_all_columns_wrap(int set)
+static void set_all_columns_truncate(int set)
{
int i;
for (i = 0; i < __NCOLUMNS; i++)
- infos[i].wrap = set;
+ infos[i].truncate = set;
}
/*
@@ -257,8 +184,7 @@ static int column_name_to_id(const char *name, size_t namesz)
if (!strncasecmp(name, cn, namesz) && !*(cn + namesz))
return i;
}
-
- errx(EXIT_FAILURE, _("unknown column: %s"), name);
+ warnx(_("unknown column: %s"), name);
return -1;
}
@@ -278,6 +204,7 @@ static int set_columns(const char *str)
for (p = str; p && *p; p++) {
const char *end = NULL;
+ int id;
if (!begin)
begin = p; /* begin of the column name */
@@ -290,7 +217,10 @@ static int set_columns(const char *str)
if (end <= begin)
return -1;
- columns[ ncolumns++ ] = column_name_to_id(begin, end - begin);
+ id = column_name_to_id(begin, end - begin);
+ if (id == -1)
+ return -1;
+ columns[ ncolumns++ ] = id;
begin = NULL;
if (end && !*end)
break;
@@ -298,136 +228,7 @@ static int set_columns(const char *str)
return 0;
}
-/* TODO: move to lib/terminal.c */
-static int terminal_get_width(void)
-{
-#ifdef TIOCGSIZE
- struct ttysize t_win;
-#endif
-#ifdef TIOCGWINSZ
- struct winsize w_win;
-#endif
- const char *cp;
-
-#ifdef TIOCGSIZE
- if (ioctl (0, TIOCGSIZE, &t_win) == 0)
- return t_win.ts_cols;
-#endif
-#ifdef TIOCGWINSZ
- if (ioctl (0, TIOCGWINSZ, &w_win) == 0)
- return w_win.ws_col;
-#endif
- cp = getenv("COLUMNS");
- if (cp)
- return strtol(cp, NULL, 10);
- return 80;
-}
-
-static void recount_widths(void)
-{
- int i, width = 0, ignore_wraps;
-
- /* set minimal width (= size of column header) */
- for (i = 0; i < ncolumns; i++) {
- const char *name = get_column_name(i);
- size_t len = mbs_width(name);
- float hint = get_column_whint(i);
-
- if (get_column_width(i) < len)
- /* enlarge to small columns */
- set_column_width(i, len);
-
- else if (hint >= 1)
- /* set absolute widths */
- set_column_width(i, (int) hint);
- }
-
- /* count used space */
- for (i = 0; i < ncolumns; i++)
- width += get_column_width(i) + (is_last_column(i) ? 0 : 1);
-
- if (width == termwidth)
- return;
-
- if (width < termwidth) {
- /* cool, use the extra space for the last column */
- i = ncolumns - 1;
- set_column_width(i, get_column_width(i) + (termwidth - width));
-
- return;
- }
-
- /* bad, we have to reduce output width, this is done in two steps:
- * 1/ reduce columns with a relative width (see colinfo.whint) and
- * without wrap flag (this columns could be truncated)
- * 2) reduce columns with a relative width with wrap flag
- */
- ignore_wraps = 1;
- while(width > termwidth) {
- int org = width;
- for (i = ncolumns - 1; i >= 0 && width > termwidth; i--) {
- float hint = get_column_whint(i);
- int w = get_column_width(i);
-
- if (hint > 1)
- /* never truncate columns with absolute sizes */
- continue;
-
- if (get_column_id(i) == COL_TARGET && (flags & FL_TREE))
- /* never truncate the tree */
- continue;
-
- if (ignore_wraps && get_column_wrap(i))
- continue;
-
- if (w > hint * termwidth) {
- set_column_width(i, w - 1);
- width--;
- }
- }
-
- if (org == width) {
- if (ignore_wraps)
- ignore_wraps = 0;
- else
- break;
- }
- }
-/*
- fprintf(stderr, "terminal: %d, output: %d\n", termwidth, width);
- for (i = 0; i < ncolumns; i++)
- fprintf(stderr, "width: %s=%d [%d]\n",
- get_column_name(i),
- get_column_width(i),
- (int) (get_column_whint(i) * termwidth));
-*/
-}
-
-static char *get_treenode_ascii_art(struct treenode *node,
- char *buf, size_t *bufsz)
-{
- const char *sym;
- size_t len;
-
- if (!node->parent)
- return buf;
- else {
- buf = get_treenode_ascii_art(node->parent, buf, bufsz);
- if (!buf)
- return NULL;
- sym = node->next ? tree_symbols->vert : " ";
- }
- len = strlen(sym);
-
- if (*bufsz < len)
- return NULL; /* no space, internal error */
-
- memcpy(buf, sym, len);
- *bufsz -= len;
- return buf + len;
-}
-
-/* Returns LABEl or UUID */
+/* Returns LABEL or UUID */
static const char *get_tag(mnt_fs *fs, const char *tagname)
{
const char *t, *v, *res;
@@ -445,37 +246,8 @@ static const char *get_tag(mnt_fs *fs, const char *tagname)
return res;
}
-static const char *get_tree_target(mnt_fs *fs, char *buf, size_t bufsz)
-{
- struct treenode *node;
- const char *target;
- char *p = buf;
-
- node = (struct treenode *) mnt_fs_get_userdata(fs);
- if (!node)
- return NULL;
-
- target = mnt_fs_get_target(fs);
- if (!target)
- return NULL;
-
- if (node->parent) {
- p = get_treenode_ascii_art(node->parent, buf, &bufsz);
- if (!p)
- return NULL;
- }
-
- if (node->next)
- snprintf(p, bufsz, "%s%s", tree_symbols->branch, target);
- else if (node->parent)
- snprintf(p, bufsz, "%s%s", tree_symbols->right, target);
- else
- snprintf(p, bufsz, "%s", target); /* root node */
-
- return buf;
-}
-
-static const char *get_column_data(mnt_fs *fs, int num)
+/* reads FS data from libmount */
+static const char *get_data(mnt_fs *fs, int num)
{
const char *str = NULL;
@@ -494,8 +266,7 @@ static const char *get_column_data(mnt_fs *fs, int num)
}
break;
case COL_TARGET:
- str = flags & FL_TREE ? get_tree_target(fs, treebuf, termwidth) :
- mnt_fs_get_target(fs);
+ str = mnt_fs_get_target(fs);
break;
case COL_FSTYPE:
str = mnt_fs_get_fstype(fs);
@@ -512,180 +283,85 @@ static const char *get_column_data(mnt_fs *fs, int num)
default:
break;
}
-
- return str ? str : "-";
-}
-
-/* TODO: move to lib/mbalign.c */
-#ifdef HAVE_WIDECHAR
-static size_t wc_truncate (wchar_t *wc, size_t width)
-{
- size_t cells = 0;
- int next_cells = 0;
-
- while (*wc)
- {
- next_cells = wcwidth (*wc);
- if (next_cells == -1) /* non printable */
- {
- *wc = 0xFFFD; /* L'\uFFFD' (replacement char) */
- next_cells = 1;
- }
- if (cells + next_cells > width)
- break;
- cells += next_cells;
- wc++;
- }
- *wc = L'\0';
- return cells;
-}
-#endif
-
-/* TODO: move to lib/mbalign.c */
-static size_t mbs_truncate(char *str, size_t width)
-{
- size_t bytes = strlen(str) + 1;
-#ifdef HAVE_WIDECHAR
- size_t sz = mbs_width(str);
- wchar_t *wcs = NULL;
- int rc = -1;
-
- if (sz <= width)
- return sz; /* truncate is unnecessary */
-
- if (sz == (size_t) -1)
- goto done;
-
- wcs = malloc(sz * sizeof(wchar_t));
- if (!wcs)
- goto done;
-
- if (!mbstowcs(wcs, str, sz))
- goto done;
- rc = wc_truncate(wcs, width);
- wcstombs(str, wcs, bytes);
-done:
- free(wcs);
- return rc;
-#else
- if (width < bytes) {
- str[width] = '\0';
- return width;
- }
- return bytes; /* truncate is unnecessary */
-#endif
+ return str;
}
-static void print_column_data(const char *data0, int num)
+/* adds one line to the output @tab */
+static struct tt_line *add_line(struct tt *tt, mnt_fs *fs,
+ struct tt_line *parent)
{
- size_t len, wrap, i;
- int width;
- char *data = (char *) data0;
-
- if (flags & FL_RAW) {
- fputs(data, stdout);
- if (!is_last_column(num))
- fputc(' ', stdout);
- return;
- }
-
- /* note that 'len' and 'width' is number of cells, not bytes */
- len = mbs_width(data);
+ int i;
+ struct tt_line *line = tt_add_line(tt, parent);
- if (!len || len == (size_t) -1) {
- len = 0;
- data = NULL;
+ if (!line) {
+ warn(_("failed to add line to output"));
+ return NULL;
}
+ for (i = 0; i < ncolumns; i++)
+ tt_line_set_data(line, i, get_data(fs, i));
- width = get_column_width(num);
- wrap = get_column_wrap(num);
-
- if (is_last_column(num) && len < width)
- width = len;
-
- if (len > width && !wrap) {
- data = strdup(data);
- if (data)
- len = mbs_truncate(data, width);
- if (!data || len == (size_t) -1) {
- len = 0;
- data = NULL;
- }
- }
- if (data)
- fputs(data, stdout);
- for (i = len; i < width; i++) /* padding */
- fputc(' ', stdout);
-
- if (!is_last_column(num)) {
- if (len > width && wrap) {
- fputc('\n', stdout);
-
- for (i = 0; i <= num; i++)
- printf("%*s ",
- -get_column_width(i), " ");
- } else
- fputc(' ', stdout); /* columns separator */
- }
- if (data != data0)
- free(data);
+ return line;
}
-static void print_fs(mnt_fs *fs, int line)
+/* reads filesystems from @tb (libmount) and fillin @tab (output table) */
+static int create_treenode(struct tt *tt, mnt_tab *tb,
+ mnt_fs *fs, struct tt_line *parent_line)
{
- int i;
-
- /* print header */
- if (!(flags & FL_NOHEADINGS) && !line) {
- for (i = 0; i < ncolumns; i++)
- print_column_data(get_column_name(i), i);
- printf("\n");
- }
+ mnt_fs *chld = NULL;
+ mnt_iter *itr = NULL;
+ struct tt_line *line;
+ int rc = -1;
- /* print data */
- for (i = 0; i < ncolumns; i++) {
- const char *data = get_column_data(fs, i);
- print_column_data(data, i);
+ if (!fs) {
+ /* first call, get root FS */
+ if (mnt_tab_get_root_fs(tb, &fs))
+ goto leave;
+ parent_line = NULL;
}
- printf("\n");
-}
-static void set_widths(mnt_fs *fs)
-{
- int i;
+ itr = mnt_new_iter(MNT_ITER_FORWARD);
+ if (!itr)
+ goto leave;
- for (i = 0; i < ncolumns; i++) {
- const char *data = get_column_data(fs, i);
- size_t len = data ? mbs_width(data) : 0;
- int old = get_column_width(i);
+ line = add_line(tt, fs, parent_line);
+ if (!line)
+ goto leave;
- if (old < len)
- set_column_width(i, len);
+ /*
+ * add all children to the output table
+ */
+ while(mnt_tab_next_child_fs(tb, itr, fs, &chld) == 0) {
+ if (create_treenode(tt, tb, chld, line))
+ goto leave;
}
+ rc = 0;
+leave:
+ mnt_free_iter(itr);
+ return rc;
}
+/* calls libmount fstab/mtab/mountinfo parser */
static mnt_tab *parse_tabfile(const char *path)
{
mnt_tab *tb = mnt_new_tab(path);
- if (!tb)
+ if (!tb) {
+ warn(_("failed to initialize libmount tab"));
return NULL;
-
- if (mnt_tab_parse_file(tb) != 0)
- goto err;
-
+ }
+ if (mnt_tab_parse_file(tb) != 0) {
+ mnt_free_tab(tb);
+ warn(_("can't read: %s"), path);
+ return NULL;
+ }
if (mnt_tab_get_nerrs(tb)) {
char buf[BUFSIZ];
mnt_tab_strerror(tb, buf, sizeof(buf));
warnx(_("%s: parse error: %s"), path, buf);
}
return tb;
-err:
- mnt_free_tab(tb);
- err(EXIT_FAILURE, _("can't read: %s"), path);
-
- return NULL;
}
+/* filter function for libmount (mnt_tab_find_next_fs()) */
static int match_func(mnt_fs *fs, void *data)
{
int rc = flags & FL_INVERT ? 1 : 0;
@@ -710,6 +386,7 @@ static int match_func(mnt_fs *fs, void *data)
return !rc;
}
+/* iterate over filesystems in @tb */
static mnt_fs *get_next_fs(mnt_tab *tb, mnt_iter *itr)
{
mnt_fs *fs = NULL;
@@ -753,89 +430,8 @@ again:
goto again;
}
}
- return fs;
-}
-
-static struct treenode *create_treenode(mnt_tab *tb, mnt_fs *fs)
-{
- mnt_fs *chld = NULL;
- mnt_iter *itr = NULL;
- struct treenode *node = NULL;
-
- if (!fs) {
- /* first call - start with root FS and initialize tree buffer */
- if (mnt_tab_get_root_fs(tb, &fs))
- goto err;
-
- treebuf = malloc(termwidth);
- if (!treebuf)
- goto err;
- }
-
- itr = mnt_new_iter(MNT_ITER_FORWARD);
- if (!itr)
- goto err;
-
- node = calloc(1, sizeof(*node));
- if (!node)
- goto err;
-
- node->fs = fs;
- mnt_fs_set_userdata(fs, (void *) node);
-
- while(mnt_tab_next_child_fs(tb, itr, fs, &chld) == 0) {
- struct treenode *chnode;
-
- chnode = create_treenode(tb, chld);
- if (!chnode)
- break;
-
- chnode->parent = node;
-
- if (node->last)
- node->last->next = chnode;
- else
- node->first = chnode;
-
- node->last = chnode;
- }
-
- return node;
-
-err:
- if (!fs)
- free(treebuf);
- free(node);
- mnt_free_iter(itr);
- return NULL;
-}
-
-static void print_treenode(struct treenode *node, int line)
-{
- print_fs(node->fs, line++);
-
- /* print children */
- node = node->first;
- while(node) {
- print_treenode(node, line++);
- node = node->next;
- }
-}
-
-static void free_treenode(struct treenode *node)
-{
- struct treenode *chld = node->first;
-
- if (!node->parent) /* root node */
- free(treebuf);
- while(chld) {
- struct treenode *next = chld->next;
- free_treenode(chld);
- chld = next;
- }
-
- free(node);
+ return fs;
}
static int __attribute__((__noreturn__)) usage(FILE *out)
@@ -884,12 +480,18 @@ errx_mutually_exclusive(const char *opts)
int main(int argc, char *argv[])
{
+ /* libmount */
+ mnt_tab *tb = NULL;
+ mnt_iter *itr = NULL;
+ mnt_fs *fs = NULL;
char *tabfile = NULL;
int direction = MNT_ITER_FORWARD;
- mnt_tab *tb;
- mnt_iter *itr;
- mnt_fs *fs = NULL;
- int c, ct = 0;
+
+ /* table.h */
+ struct tt *tt = NULL;
+ int tt_flags = 0;
+
+ int i, c, rc = EXIT_FAILURE;
struct option longopts[] = {
{ "ascii", 0, 0, 'a' },
@@ -928,13 +530,13 @@ int main(int argc, char *argv[])
columns[ncolumns++] = COL_OPTIONS;
/* default output format */
- flags |= FL_TREE;
+ tt_flags |= TT_FL_TREE;
while ((c = getopt_long(argc, argv,
"cd:ehifo:O:klmnrst:uS:T:", longopts, NULL)) != -1) {
switch(c) {
case 'a':
- tree_symbols = &ascii_tree_symbols;
+ tt_flags |= TT_FL_ASCII;
break;
case 'c':
flags |= FL_CANONICALIZE;
@@ -961,27 +563,28 @@ int main(int argc, char *argv[])
flags |= FL_FIRSTONLY;
break;
case 'u':
- set_all_columns_wrap(TRUE);
+ set_all_columns_truncate(FALSE);
break;
case 'o':
- set_columns(optarg);
+ if (set_columns(optarg))
+ exit(EXIT_FAILURE);
break;
case 'O':
set_match(COL_OPTIONS, optarg);
break;
- case 'm':
+ case 'm': /* mtab */
if (tabfile)
errx_mutually_exclusive("--{fstab,mtab,kernel}");
tabfile = _PATH_MOUNTED;
- flags &= ~FL_TREE; /* disable the default */
+ tt_flags &= ~TT_FL_TREE;
break;
- case 's':
+ case 's': /* fstab */
if (tabfile)
errx_mutually_exclusive("--{fstab,mtab,kernel}");
tabfile = _PATH_MNTTAB;
- flags &= ~FL_TREE; /* disable the default */
+ flags &= ~TT_FL_TREE;
break;
- case 'k':
+ case 'k': /* kernel (mountinfo) */
if (tabfile)
errx_mutually_exclusive("--{fstab,mtab,kernel}");
tabfile = _PATH_PROC_MOUNTINFO;
@@ -990,20 +593,21 @@ int main(int argc, char *argv[])
set_match(COL_FSTYPE, optarg);
break;
case 'r':
- if (!(flags & FL_TREE) && !(flags & FL_RAW))
+ if (!(tt_flags & TT_FL_TREE) &&
+ !(tt_flags & TT_FL_RAW))
errx_mutually_exclusive("--{raw,list}");
- flags &= ~FL_TREE; /* disable the default */
- flags |= FL_RAW; /* enable raw */
+ tt_flags &= ~TT_FL_TREE; /* disable the default */
+ tt_flags |= TT_FL_RAW; /* enable raw */
break;
case 'l':
- if (flags & FL_RAW)
+ if (tt_flags & TT_FL_RAW)
errx_mutually_exclusive("--{raw,list}");
- flags &= ~FL_TREE; /* disable the default */
+ tt_flags &= ~TT_FL_TREE; /* disable the default */
break;
case 'n':
- flags |= FL_NOHEADINGS;
+ tt_flags |= TT_FL_NOHEADINGS;
break;
case 'S':
set_match(COL_SOURCE, optarg);
@@ -1019,16 +623,14 @@ int main(int argc, char *argv[])
}
}
- if (!tabfile)
+ if (!tabfile) {
tabfile = _PATH_PROC_MOUNTINFO;
-#ifdef HAVE_WIDECHAR
- /* non-UTF terminal */
- if ((flags & FL_TREE) && tree_symbols != &ascii_tree_symbols &&
- strcmp(nl_langinfo(CODESET), "UTF-8"))
- tree_symbols = &ascii_tree_symbols;
-#endif
-
+ if (access(tabfile, R_OK)) { /* old kernel? */
+ tabfile = _PATH_PROC_MOUNTS;
+ tt_flags &= ~TT_FL_TREE;
+ }
+ }
if (optind < argc && (get_match(COL_SOURCE) || get_match(COL_TARGET)))
errx(EXIT_FAILURE, _(
"options --target and --source can't be used together "
@@ -1039,58 +641,75 @@ int main(int argc, char *argv[])
if (optind < argc)
set_match(COL_TARGET, argv[optind++]); /* mountpoint */
+ if (!is_listall_mode() || (flags & FL_FIRSTONLY))
+ tt_flags &= ~TT_FL_TREE;
+
+ /*
+ * initialize libmount
+ */
tb = parse_tabfile(tabfile);
if (!tb)
- return EXIT_FAILURE;
+ goto leave;
itr = mnt_new_iter(direction);
- if (!itr)
- err(EXIT_FAILURE, _("failed to initialize libmount iterator"));
-
+ if (!itr) {
+ warn(_("failed to initialize libmount iterator"));
+ goto leave;
+ }
cache = mnt_new_cache();
- if (!cache)
- err(EXIT_FAILURE, _("failed to initialize libmount cache"));
-
+ if (!cache) {
+ warn(_("failed to initialize libmount cache"));
+ goto leave;
+ }
mnt_tab_set_cache(tb, cache);
- termwidth = terminal_get_width();
+ /*
+ * initialize output formatting (table.h)
+ */
+ tt = tt_new_table(tt_flags);
+ if (!tt) {
+ warn(_("failed to initialize output table"));
+ goto leave;
+ }
+ for (i = 0; i < ncolumns; i++) {
+ int fl = get_column_truncate(i) ? TT_FL_TRUNCATE : 0;
- if (flags & FL_TREE) {
- struct treenode *tree = create_treenode(tb, NULL);
- if (!tree)
- err(EXIT_FAILURE, _("failed to create tree"));
+ if (get_column_id(i) == COL_TARGET && (tt_flags & TT_FL_TREE))
+ fl |= TT_FL_TREE;
- while (mnt_tab_next_fs(tb, itr, &fs) == 0) {
- set_widths(fs);
- ct++;
- }
- recount_widths();
- print_treenode(tree, 0);
- free_treenode(tree);
- } else {
- /* set width */
-
- if (!(flags & FL_RAW)) {
- while((fs = get_next_fs(tb, itr))) {
- set_widths(fs);
- if (flags & FL_FIRSTONLY)
- break;
- }
- ct = 0;
- mnt_reset_iter(itr, -1);
- recount_widths();
+ if (!tt_define_column(tt, get_column_name(i),
+ get_column_whint(i), fl)) {
+ warn(_("failed to initialize output column"));
+ goto leave;
}
+ }
- /* Print */
+ /*
+ * Fill in data to the output table
+ */
+ if (tt_flags & TT_FL_TREE) {
+ if (create_treenode(tt, tb, NULL, NULL))
+ goto leave;
+ } else {
while((fs = get_next_fs(tb, itr))) {
- print_fs(fs, ct++);
+ if (!add_line(tt, fs, NULL))
+ goto leave;
if (flags & FL_FIRSTONLY)
break;
}
}
+
+ /*
+ * Print the output table
+ */
+ tt_print_table(tt);
+ rc = EXIT_SUCCESS;
+leave:
+ tt_free_table(tt);
+
mnt_free_tab(tb);
mnt_free_cache(cache);
mnt_free_iter(itr);
- return ct ? EXIT_SUCCESS : 2;
+ return rc;
}