diff options
| -rw-r--r-- | bash-completion/findmnt | 1 | ||||
| -rw-r--r-- | bash-completion/lsblk | 1 | ||||
| -rw-r--r-- | include/strutils.h | 3 | ||||
| -rw-r--r-- | include/ttyutils.h | 27 | ||||
| -rw-r--r-- | include/xalloc.h | 17 | ||||
| -rw-r--r-- | lib/strutils.c | 14 | ||||
| -rw-r--r-- | libsmartcols/docs/libsmartcols-sections.txt | 5 | ||||
| -rw-r--r-- | libsmartcols/src/cell.c | 62 | ||||
| -rw-r--r-- | libsmartcols/src/column.c | 40 | ||||
| -rw-r--r-- | libsmartcols/src/libsmartcols.h.in | 7 | ||||
| -rw-r--r-- | libsmartcols/src/libsmartcols.sym | 5 | ||||
| -rw-r--r-- | libsmartcols/src/print.c | 77 | ||||
| -rw-r--r-- | libsmartcols/src/smartcolsP.h | 6 | ||||
| -rw-r--r-- | misc-utils/findmnt.8.adoc | 3 | ||||
| -rw-r--r-- | misc-utils/findmnt.c | 23 | ||||
| -rw-r--r-- | misc-utils/findmnt.h | 1 | ||||
| -rw-r--r-- | misc-utils/lsblk-mnt.c | 7 | ||||
| -rw-r--r-- | misc-utils/lsblk.8.adoc | 3 | ||||
| -rw-r--r-- | misc-utils/lsblk.c | 16 | ||||
| -rw-r--r-- | misc-utils/lsblk.h | 1 |
20 files changed, 309 insertions, 10 deletions
diff --git a/bash-completion/findmnt b/bash-completion/findmnt index 859439472b..2eb23446f7 100644 --- a/bash-completion/findmnt +++ b/bash-completion/findmnt @@ -111,6 +111,7 @@ _findmnt_module() --evaluate --tab-file --first-only + --hyperlink --invert --json --list diff --git a/bash-completion/lsblk b/bash-completion/lsblk index 41c2b2c8fe..ff82685813 100644 --- a/bash-completion/lsblk +++ b/bash-completion/lsblk @@ -71,6 +71,7 @@ _lsblk_module() --fs --filter --highlight + --hyperlink --ct --ct-filter --help diff --git a/include/strutils.h b/include/strutils.h index aa8c002d59..b7a03c1482 100644 --- a/include/strutils.h +++ b/include/strutils.h @@ -14,6 +14,7 @@ #include <stdio.h> #include <errno.h> #include <time.h> +#include <stdbool.h> #include "c.h" @@ -58,6 +59,8 @@ extern void strtotimespec_or_err(const char *str, struct timespec *ts, const char *errmesg); extern time_t strtotime_or_err(const char *str, const char *errmesg); +extern bool hyperlinkwanted_or_err(const char *mode, const char *errmesg); + extern int isdigit_strend(const char *str, const char **end); #define isdigit_string(_s) isdigit_strend(_s, NULL) diff --git a/include/ttyutils.h b/include/ttyutils.h index 39182b66bb..46df3cddd2 100644 --- a/include/ttyutils.h +++ b/include/ttyutils.h @@ -7,6 +7,7 @@ #ifndef UTIL_LINUX_TTYUTILS_H #define UTIL_LINUX_TTYUTILS_H +#include <stdio.h> #include <stdlib.h> #include <termios.h> #include <limits.h> @@ -210,4 +211,30 @@ static inline void reset_virtual_console(struct termios *tp, int flags) tp->c_cc[VEOL2] = _POSIX_VDISABLE; } +#define UL_OSC8 "\033]8" /* operating system command) */ +#define UL_ST "\033\\" /* string terminator */ + +/* OSC8 hyperlink is composed from: + * + * UL_HYPERLINK_START UL_HYPERLINK_PARAMS <uri> UL_HYPERLINK_LINK <link-text> UL_HYPERLINK_END + * + * Alternatively, BEL (\a) can be used instead of ST. + */ +#define UL_HYPERLINK_START UL_OSC8 +#define UL_HYPERLINK_PARAMS ";;" +#define UL_HYPERLINK_LINK UL_ST +#define UL_HYPERLINK_END (UL_OSC8 ";;" UL_ST) + +static inline void ul_fputs_hyperlink(const char *uri, const char *link, FILE *out) +{ + fputs(UL_HYPERLINK_START, out); + fputs(UL_HYPERLINK_PARAMS, out); + fputs(uri, out); + + fputs(UL_HYPERLINK_LINK, out); + fputs(link, out); + + fputs(UL_HYPERLINK_END, out); +} + #endif /* UTIL_LINUX_TTYUTILS_H */ diff --git a/include/xalloc.h b/include/xalloc.h index 1ece82d564..e8e427c862 100644 --- a/include/xalloc.h +++ b/include/xalloc.h @@ -193,4 +193,21 @@ char *xgethostname(void) return name; } +static inline +__attribute__((warn_unused_result)) +char *xgethosturi(const char *proto) +{ + char *n = xgethostname(); + char *uri = NULL; + + if (!proto) + proto = "file://"; + if (!n) + return xstrdup(proto); + + xasprintf(&uri, "%s%s", proto, n); + free(n); + return uri; +} + #endif diff --git a/lib/strutils.c b/lib/strutils.c index 4590aa9114..0cf0da96b6 100644 --- a/lib/strutils.c +++ b/lib/strutils.c @@ -524,6 +524,20 @@ time_t strtotime_or_err(const char *str, const char *errmesg) return (time_t) user_input; } +bool hyperlinkwanted_or_err(const char *mode, const char *errmesg) +{ + if (mode && strcmp(mode, "never") == 0) + return false; + + if (mode && strcmp(mode, "always") == 0) + return true; + + if (!mode || strcmp(mode, "auto") == 0) + return isatty(STDOUT_FILENO) ? true : false; + + errx(EXIT_FAILURE, "%s: '%s'", errmesg, mode); +} + /* * Converts stat->st_mode to ls(1)-like mode string. The size of "str" must * be 11 bytes. diff --git a/libsmartcols/docs/libsmartcols-sections.txt b/libsmartcols/docs/libsmartcols-sections.txt index 5f4c736a74..94bb9ef058 100644 --- a/libsmartcols/docs/libsmartcols-sections.txt +++ b/libsmartcols/docs/libsmartcols-sections.txt @@ -2,17 +2,20 @@ <FILE>cell</FILE> libscols_cell scols_cell_copy_content +scols_cell_disable_uri scols_cell_get_alignment scols_cell_get_color scols_cell_get_data scols_cell_get_datasiz scols_cell_get_flags +scols_cell_get_uri scols_cell_get_userdata scols_cell_refer_data scols_cell_refer_memory scols_cell_set_color scols_cell_set_data scols_cell_set_flags +scols_cell_set_uri scols_cell_set_userdata scols_cmpstr_cells scols_reset_cell @@ -30,6 +33,7 @@ scols_column_get_name scols_column_get_name_as_shellvar scols_column_get_safechars scols_column_get_table +scols_column_get_uri scols_column_get_whint scols_column_get_width scols_column_get_wrap_data @@ -51,6 +55,7 @@ scols_column_set_json_type scols_column_set_name scols_column_set_properties scols_column_set_safechars +scols_column_set_uri scols_column_set_whint scols_column_set_wrapfunc scols_copy_column diff --git a/libsmartcols/src/cell.c b/libsmartcols/src/cell.c index df45667ec5..4c279166e8 100644 --- a/libsmartcols/src/cell.c +++ b/libsmartcols/src/cell.c @@ -47,6 +47,7 @@ int scols_reset_cell(struct libscols_cell *ce) /*DBG(CELL, ul_debugobj(ce, "reset"));*/ free(ce->data); free(ce->color); + free(ce->uri); memset(ce, 0, sizeof(*ce)); return 0; } @@ -245,6 +246,65 @@ const char *scols_cell_get_color(const struct libscols_cell *ce) } /** + * scols_cell_set_uri: + * @ce: a pointer to a struct libscols_cell instance + * @uri: URI string + * + * Set the URI of @ce to @uri. + * + * Returns: 0, a negative value in case of an error. + * + * Since: 2.41 + */ +int scols_cell_set_uri(struct libscols_cell *ce, const char *uri) +{ + if (!ce) + return -EINVAL; + + return strdup_to_struct_member(ce, uri, uri); +} + +/** + * scols_cell_get_uri: + * @ce: a pointer to a struct libscols_cell instance + * + * The function returns the URI setting, but it may not necessarily be the final + * URI used in the output. This is because the column may define a URI prefix or + * the cell content may be used as part of the URI. + * + * Returns: the current URI of @ce. + * + * Since: 2.41 + */ +const char *scols_cell_get_uri(const struct libscols_cell *ce) +{ + if (!ce) + return NULL; + + return ce->uri; +} + +/** + * scols_cell_disable_uri: + * @ce: a pointer to a struct libscols_cell instance + * @disable: 1 or 0 + * + * Force the library to ignore the cell and column URI setting and print the + * content as a regular string. + * + * Returns: 0, a negative value in case of an error. + * + * Since: 2.41 + */ +int scols_cell_disable_uri(struct libscols_cell *ce, int disable) +{ + if (!ce) + return -EINVAL; + ce->no_uri = disable ? 1 : 0; + return 0; +} + +/** * scols_cell_set_flags: * @ce: a pointer to a struct libscols_cell instance * @flags: SCOLS_CELL_FL_* flags @@ -322,6 +382,8 @@ int scols_cell_copy_content(struct libscols_cell *dest, if (!rc) rc = scols_cell_set_color(dest, scols_cell_get_color(src)); if (!rc) + rc = scols_cell_set_uri(dest, scols_cell_get_uri(src)); + if (!rc) dest->userdata = src->userdata; DBG(CELL, ul_debugobj(src, "copy")); diff --git a/libsmartcols/src/column.c b/libsmartcols/src/column.c index 27988c2702..28def30605 100644 --- a/libsmartcols/src/column.c +++ b/libsmartcols/src/column.c @@ -72,6 +72,8 @@ void scols_unref_column(struct libscols_column *cl) list_del(&cl->cl_columns); scols_reset_cell(&cl->header); free(cl->color); + free(cl->uri); + ul_buffer_free_data(&cl->uri_buf); free(cl->safechars); free(cl->wrap_data); free(cl->shellvar); @@ -101,6 +103,8 @@ struct libscols_column *scols_copy_column(const struct libscols_column *cl) if (scols_column_set_color(ret, cl->color)) goto err; + if (scols_column_set_uri(ret, cl->uri)) + goto err; if (scols_cell_copy_content(&ret->header, &cl->header)) goto err; @@ -431,6 +435,42 @@ const char *scols_column_get_color(const struct libscols_column *cl) return cl->color; } +/** + * scols_column_set_uri: + * @cl: a pointer to a struct libscols_column instance + * @uri: URI string + * + * The default URI prefix for cells is used when creating hyperlinks. However, + * it can still be disabled for selected cells using scols_cell_disable_uri(). + * See also scols_cell_set_uri(). + * + * The final cell URI is composed of the column-uri, cell-uri, and cell-data. + * The column-uri and/or cell-uri must be set for this feature to be enabled. + * + * column-uri cell-uri cell-data final-URI link + * ----------------------------------------------------------------------------------- + * file://host/path/foo.txt foo file://host/path/foo.txt foo + * file://host /path/foo.txt foo file://host/path/foo.txt foo + * file://host /path/foo.txt file://host/path/foo.txt /path/foo.txt + * + * + * Returns: 0, a negative value in case of an error. + */ +int scols_column_set_uri(struct libscols_column *cl, const char *uri) +{ + return strdup_to_struct_member(cl, uri, uri); +} + +/** + * scols_column_get_uri: + * @cl: a pointer to a struct libscols_column instance + * + * Returns: The current URI setting of the column @cl. + */ +const char *scols_column_get_uri(const struct libscols_column *cl) +{ + return cl->uri; +} /** * scols_wrapnl_nextchunk: diff --git a/libsmartcols/src/libsmartcols.h.in b/libsmartcols/src/libsmartcols.h.in index edee65b7e5..1acff2f0e9 100644 --- a/libsmartcols/src/libsmartcols.h.in +++ b/libsmartcols/src/libsmartcols.h.in @@ -207,6 +207,10 @@ extern size_t scols_cell_get_datasiz(struct libscols_cell *ce); extern int scols_cell_set_color(struct libscols_cell *ce, const char *color); extern const char *scols_cell_get_color(const struct libscols_cell *ce); +extern int scols_cell_set_uri(struct libscols_cell *ce, const char *uri); +extern const char *scols_cell_get_uri(const struct libscols_cell *ce); +extern int scols_cell_disable_uri(struct libscols_cell *ce, int disable); + extern int scols_cell_set_flags(struct libscols_cell *ce, int flags); extern int scols_cell_get_flags(const struct libscols_cell *ce); extern int scols_cell_get_alignment(const struct libscols_cell *ce); @@ -251,6 +255,9 @@ extern int scols_column_set_color(struct libscols_column *cl, const char *color) extern const char *scols_column_get_color(const struct libscols_column *cl); extern struct libscols_table *scols_column_get_table(const struct libscols_column *cl); +extern int scols_column_set_uri(struct libscols_column *cl, const char *uri); +extern const char *scols_column_get_uri(const struct libscols_column *cl); + extern int scols_column_set_name(struct libscols_column *cl, const char *name); extern const char *scols_column_get_name(struct libscols_column *cl); extern const char *scols_column_get_name_as_shellvar(struct libscols_column *cl); diff --git a/libsmartcols/src/libsmartcols.sym b/libsmartcols/src/libsmartcols.sym index e74d928627..ce77b0df3c 100644 --- a/libsmartcols/src/libsmartcols.sym +++ b/libsmartcols/src/libsmartcols.sym @@ -250,4 +250,9 @@ SMARTCOLS_2.41 { scols_line_sprintf; scols_line_vprintf_column; scols_line_sprintf_column; + scols_cell_set_uri; + scols_cell_get_uri; + scols_cell_disable_uri; + scols_column_set_uri; + scols_column_get_uri; } SMARTCOLS_2.40; diff --git a/libsmartcols/src/print.c b/libsmartcols/src/print.c index 89d6aba092..1530333021 100644 --- a/libsmartcols/src/print.c +++ b/libsmartcols/src/print.c @@ -24,6 +24,7 @@ #include "mbsalign.h" #include "carefulputc.h" #include "smartcolsP.h" +#include "ttyutils.h" /* Fallback for symbols * @@ -307,6 +308,50 @@ static void fputs_color_line_close(struct libscols_table *tb) fputs_color_reset(tb); } +/* @buf is the cell data generated by __cursor_to_buffer(). We cannot use + * scols_cell_get_data() directly because there may be a defined wrap function + * and we need the URI for the segment of the data. For example, when the cell + * contains multiple filenames. + * + * The number of URIs can be enormous (due to the number of lines in the table). + * Therefore, the goal is to avoid allocation, and a buffer specific to each + * column is used and shared for all lines. + */ +static const char *mk_cell_uri(struct libscols_column *cl, + struct libscols_cell *ce, + struct ul_buffer *buf) +{ + char *path; + + /* URI disabled at all */ + if (ce->no_uri) + return NULL; + + /* No column prefix, return cell URI (or NULL if undefined) */ + if (!cl->uri) + return ce->uri; + + /* Compose URI from column-uri + path. The path is ce->uri or cell data. */ + path = ce->uri; + + if (!path && buf) { + /* The buffer may already contain tree data, so we need to skip it. */ + path = ul_buffer_get_pointer(buf, SCOLS_BUFPTR_TREEEND); + if (!path) + path = ul_buffer_get_string(buf, NULL, NULL); + } + + if (!path) + return NULL; + + ul_buffer_reset_data(&cl->uri_buf); + ul_buffer_append_string(&cl->uri_buf, cl->uri); + + ul_buffer_append_string(&cl->uri_buf, path); + + return ul_buffer_get_string(&cl->uri_buf, NULL, NULL); +} + /* print padding or ASCII-art instead of data of @cl */ static void print_empty_cell(struct libscols_table *tb, struct libscols_column *cl, @@ -414,6 +459,7 @@ static int print_pending_data(struct libscols_table *tb, struct ul_buffer *buf) struct libscols_column *cl; struct libscols_cell *ce; char *data; + const char *uri = NULL; size_t i, width = 0, len = 0, bytes = 0; scols_table_get_cursor(tb, &ln, &cl, &ce); @@ -424,6 +470,9 @@ static int print_pending_data(struct libscols_table *tb, struct ul_buffer *buf) DBG(COL, ul_debugobj(cl, "printing pending data")); + if (cl->uri || ce->uri) + uri = mk_cell_uri(cl, ce, buf); + if (scols_table_is_noencoding(tb)) data = ul_buffer_get_data(buf, &bytes, &len); else @@ -444,7 +493,11 @@ static int print_pending_data(struct libscols_table *tb, struct ul_buffer *buf) } fputs_color_cell_open(tb, cl, ln, ce); - fputs(data, tb->out); + + if (uri) + ul_fputs_hyperlink(uri, data, tb->out); + else + fputs(data, tb->out); /* minout -- don't fill */ if (scols_table_is_minout(tb) && is_next_columns_empty(tb, cl, ln)) { @@ -537,7 +590,7 @@ static int print_data(struct libscols_table *tb, struct ul_buffer *buf) struct libscols_cell *ce; size_t len = 0, i, width, bytes; char *data = NULL; - const char *name = NULL; + const char *name = NULL, *uri = NULL; int is_last; assert(tb); @@ -585,6 +638,9 @@ static int print_data(struct libscols_table *tb, struct ul_buffer *buf) break; /* continue below */ } + if (cl->uri || ce->uri) + uri = mk_cell_uri(cl, ce, buf); + /* Encode. Note that 'len' and 'width' are number of glyphs not bytes. */ if (scols_table_is_noencoding(tb)) @@ -632,7 +688,20 @@ static int print_data(struct libscols_table *tb, struct ul_buffer *buf) fputs(cellpadding_symbol(tb), tb->out); len = width; } - fputs(data, tb->out); + + if (uri) { + char *link = data; + size_t skip = ul_buffer_get_pointer_length(buf, SCOLS_BUFPTR_TREEEND); + + /* Print hyperlink after tree lines */ + if (skip) { + link = data + skip; + for (i = 0; i < skip; i++) + fputc(data[i], tb->out); + } + ul_fputs_hyperlink(uri, link, tb->out); + } else + fputs(data, tb->out); } /* minout -- don't fill */ @@ -986,6 +1055,8 @@ int __scols_print_header(struct libscols_table *tb, struct ul_buffer *buf) continue; ul_buffer_reset_data(buf); + if (cl->uri) + scols_cell_disable_uri(&cl->header, 1); scols_table_set_cursor(tb, NULL, cl, &cl->header); if (cl->is_groups diff --git a/libsmartcols/src/smartcolsP.h b/libsmartcols/src/smartcolsP.h index 444661ee6a..68b46886e7 100644 --- a/libsmartcols/src/smartcolsP.h +++ b/libsmartcols/src/smartcolsP.h @@ -86,11 +86,13 @@ struct libscols_cell { char *data; size_t datasiz; char *color; + char *uri; void *userdata; int flags; size_t width; - unsigned int is_filled : 1; + unsigned int is_filled : 1, + no_uri : 1; }; extern int scols_line_move_cells(struct libscols_line *ln, size_t newn, size_t oldn); @@ -123,6 +125,8 @@ struct libscols_column { int flags; char *color; /* default column color */ + char *uri; /* default column URI prefix */ + struct ul_buffer uri_buf; /* temporary buffer to compose URIs */ char *safechars; /* do not encode this bytes */ int (*cmpfunc)(struct libscols_cell *, diff --git a/misc-utils/findmnt.8.adoc b/misc-utils/findmnt.8.adoc index f29f965421..23fb14da56 100644 --- a/misc-utils/findmnt.8.adoc +++ b/misc-utils/findmnt.8.adoc @@ -57,6 +57,9 @@ The search direction, either *forward* or *backward*. *-e*, *--evaluate*:: Convert all tags (LABEL, UUID, PARTUUID, or PARTLABEL) to the corresponding device names for the SOURCE column. It's an unusual situation, but the same tag may be duplicated (used for more devices). For this purpose, there is SOURCES (pl.) column. This column displays by multi-line cell all devices where the tag is detected by libblkid. This option makes sense for _fstab_ only. +*--hyperlink*[=_mode_]:: +Print mountpoint paths as terminal hyperlinks. The _mode_ can be set to "always", "never", or "auto". The optional argument _when_ can be set to "auto", "never", or "always". If the _when_ argument is omitted, it will default to "auto". The "auto" setting means that hyperlinks will only be used if the output is on a terminal. + *-F*, *--tab-file* _path_:: Search in an alternative file. If used with *--fstab*, *--mtab* or *--kernel*, then it overrides the default paths. If specified more than once, then tree-like output is disabled (see the *--list* option). diff --git a/misc-utils/findmnt.c b/misc-utils/findmnt.c index 236e8e7a80..736c20e038 100644 --- a/misc-utils/findmnt.c +++ b/misc-utils/findmnt.c @@ -50,6 +50,7 @@ #include "mangle.h" #include "buffer.h" #include "column-list-table.h" +#include "ttyutils.h" #include "findmnt.h" @@ -1555,9 +1556,12 @@ static void __attribute__((__noreturn__)) list_colunms(struct findmnt *findmnt) exit(EXIT_SUCCESS); } -static struct libscols_table *init_scols_table(unsigned int flags, bool use_filter) +static struct libscols_table *init_scols_table(struct findmnt *findmnt) { struct libscols_table *table = scols_new_table(); + unsigned int flags = findmnt->flags; + bool use_filter = findmnt->filter? true: false; + if (!table) { warn(_("failed to allocate output table")); goto leave; @@ -1592,6 +1596,10 @@ static struct libscols_table *init_scols_table(unsigned int flags, bool use_filt warn(_("failed to allocate output column")); goto leave; } + + if (findmnt->uri && id == COL_TARGET) + scols_column_set_uri(cl, findmnt->uri); + /* multi-line cells (now used for SOURCES) */ if (fl & SCOLS_FL_WRAP) scols_column_set_wrapfunc(cl, @@ -1688,7 +1696,8 @@ int main(int argc, char *argv[]) FINDMNT_OPT_PSEUDO, FINDMNT_OPT_REAL, FINDMNT_OPT_VFS_ALL, - FINDMNT_OPT_SHADOWED + FINDMNT_OPT_SHADOWED, + FINDMNT_OPT_HYPERLINK }; static const struct option longopts[] = { @@ -1737,6 +1746,7 @@ int main(int argc, char *argv[]) { "pseudo", no_argument, NULL, FINDMNT_OPT_PSEUDO }, { "vfs-all", no_argument, NULL, FINDMNT_OPT_VFS_ALL }, { "shadowed", no_argument, NULL, FINDMNT_OPT_SHADOWED }, + { "hyperlink", optional_argument, NULL, FINDMNT_OPT_HYPERLINK }, { "list-columns", no_argument, NULL, 'H' }, { NULL, 0, NULL, 0 } }; @@ -1930,7 +1940,11 @@ int main(int argc, char *argv[]) case FINDMNT_OPT_SHADOWED: findmnt.flags |= FL_SHADOWED; break; - + case FINDMNT_OPT_HYPERLINK: + if (hyperlinkwanted_or_err(optarg, + _("invalid hyperlink argument"))) + findmnt.uri = xgethosturi(NULL); + break; case 'H': collist = 1; break; @@ -2061,12 +2075,13 @@ int main(int argc, char *argv[]) * initialize libsmartcols */ scols_init_debug(0); - table = init_scols_table(findmnt.flags, findmnt.filter? true: false); + table = init_scols_table(&findmnt); if (!table) goto leave; init_scols_filter(table, findmnt.filter, findmnt.flags); + /* * Fill in data to the output table */ diff --git a/misc-utils/findmnt.h b/misc-utils/findmnt.h index a8ebdea1c1..5c74bddc4b 100644 --- a/misc-utils/findmnt.h +++ b/misc-utils/findmnt.h @@ -39,6 +39,7 @@ struct findmnt { struct libmnt_cache *cache; unsigned int flags; int parse_nerrors; + char *uri; struct libscols_filter *filter; }; diff --git a/misc-utils/lsblk-mnt.c b/misc-utils/lsblk-mnt.c index 81ded5ea23..3217e3f554 100644 --- a/misc-utils/lsblk-mnt.c +++ b/misc-utils/lsblk-mnt.c @@ -64,6 +64,9 @@ static void add_filesystem(struct lsblk_device *dev, struct libmnt_fs *fs) dev->fss[dev->nfss] = fs; dev->nfss++; dev->is_mounted = 1; + + if (mnt_fs_is_swaparea(fs)) + dev->is_swap = 1; } struct libmnt_fs **lsblk_device_get_filesystems(struct lsblk_device *dev, size_t *n) @@ -162,8 +165,10 @@ const char *lsblk_device_get_mountpoint(struct lsblk_device *dev) } } } - if (mnt_fs_is_swaparea(fs)) + if (mnt_fs_is_swaparea(fs)) { + dev->is_swap = 1; return "[SWAP]"; + } return mnt_fs_get_target(fs); } diff --git a/misc-utils/lsblk.8.adoc b/misc-utils/lsblk.8.adoc index 308c71e3f6..d92d3fb44c 100644 --- a/misc-utils/lsblk.8.adoc +++ b/misc-utils/lsblk.8.adoc @@ -61,6 +61,9 @@ Exclude the devices specified by the comma-separated _list_ of major device numb *-f*, *--fs*:: Output info about filesystems. This option is equivalent to *-o NAME,FSTYPE,FSVER,LABEL,UUID,FSAVAIL,FSUSE%,MOUNTPOINTS*. The authoritative information about filesystems and raids is provided by the *blkid*(8) command. +*--hyperlink*[=_mode_]:: +Print mountpoint paths as terminal hyperlinks. The _mode_ can be set to "always", "never", or "auto". The optional argument _when_ can be set to "auto", "never", or "always". If the _when_ argument is omitted, it will default to "auto". The "auto" setting means that hyperlinks will only be used if the output is on a terminal. + *-I*, *--include* _list_:: Include devices specified by the comma-separated _list_ of major device numbers. The filter is applied to the top-level devices only. This may be confusing for *--list* output format where hierarchy of the devices is not obvious. diff --git a/misc-utils/lsblk.c b/misc-utils/lsblk.c index cc1ae98b6c..6a8dc5011b 100644 --- a/misc-utils/lsblk.c +++ b/misc-utils/lsblk.c @@ -1274,10 +1274,14 @@ static void device_fill_scols_cell(struct lsblk_device *dev, ce = scols_line_get_cell(ln, colnum); if (!ce) return; + rc = datasiz ? scols_cell_refer_memory(ce, data, datasiz) : scols_cell_refer_data(ce, data); if (rc) err(EXIT_FAILURE, _("failed to add output data")); + + if (lsblk->uri && (id == COL_TARGETS || id == COL_TARGET) && dev->is_swap) + scols_cell_disable_uri(ce, 1); } static int filter_filler_cb( @@ -2407,7 +2411,8 @@ int main(int argc, char *argv[]) OPT_COUNTER_FILTER, OPT_COUNTER, OPT_HIGHLIGHT, - OPT_PROPERTIES_BY + OPT_PROPERTIES_BY, + OPT_HYPERLINK }; static const struct option longopts[] = { @@ -2424,6 +2429,7 @@ int main(int argc, char *argv[]) { "output-all", no_argument, NULL, 'O' }, { "filter", required_argument, NULL, 'Q' }, { "highlight", required_argument, NULL, OPT_HIGHLIGHT }, + { "hyperlink", optional_argument, NULL, OPT_HYPERLINK }, { "merge", no_argument, NULL, 'M' }, { "perms", no_argument, NULL, 'm' }, { "noheadings", no_argument, NULL, 'n' }, @@ -2667,6 +2673,11 @@ int main(int argc, char *argv[]) if (lsblk_set_properties_method(optarg) < 0) errtryhelp(EXIT_FAILURE); break; + case OPT_HYPERLINK: + if (hyperlinkwanted_or_err(optarg, + _("invalid hyperlink argument"))) + lsblk->uri = xgethosturi(NULL); + break; case 'H': collist = 1; break; @@ -2793,6 +2804,9 @@ int main(int argc, char *argv[]) if (fl & SCOLS_FL_WRAP) scols_column_set_wrapfunc(cl, NULL, scols_wrapzero_nextchunk, NULL); + if (lsblk->uri && (id == COL_TARGET || id == COL_TARGETS)) + scols_column_set_uri(cl, lsblk->uri); + set_column_type(ci, cl, fl); } diff --git a/misc-utils/lsblk.h b/misc-utils/lsblk.h index b2b9b40dcd..90d2df1a13 100644 --- a/misc-utils/lsblk.h +++ b/misc-utils/lsblk.h @@ -60,6 +60,7 @@ struct lsblk { size_t ncts; /* number of ct filters */ const char *sysroot; + char *uri; int flags; /* LSBLK_* */ int properties_by[__LSBLK_NMETHODS]; |
