aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCameron Katri <me@cameronkatri.com>2021-05-30 17:21:13 -0400
committerCameron Katri <me@cameronkatri.com>2021-05-30 17:21:13 -0400
commit85c2054fdbac56a5f60001d504190317b1729ee7 (patch)
tree0179f5d50ba16b0f81dea05c17fac88b0b4ec37f
downloadfreebsd-patches-85c2054fdbac56a5f60001d504190317b1729ee7.tar.gz
freebsd-patches-85c2054fdbac56a5f60001d504190317b1729ee7.tar.zst
freebsd-patches-85c2054fdbac56a5f60001d504190317b1729ee7.zip
Initial
-rw-r--r--README.md5
-rw-r--r--acpiconf-8-Add-libxo-3-support.patch352
-rw-r--r--diff-1-Add-color-support.patch238
-rw-r--r--ls-1-Allow-LSCOLORS-to-specify-an-underline.patch152
-rw-r--r--mount-8-Add-libxo-3-support.patch475
5 files changed, 1222 insertions, 0 deletions
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..97fc93b
--- /dev/null
+++ b/README.md
@@ -0,0 +1,5 @@
+# FreeBSD Patches
+
+A collection of patches for FreeBSD 14-CURRENT, that I use on my system. These have all been submitted to https://reviews.freebsd.org, just still waiting for a review.
+
+Apply with `git-am(1)`
diff --git a/acpiconf-8-Add-libxo-3-support.patch b/acpiconf-8-Add-libxo-3-support.patch
new file mode 100644
index 0000000..641c18f
--- /dev/null
+++ b/acpiconf-8-Add-libxo-3-support.patch
@@ -0,0 +1,352 @@
+From b01ad1d67883953d2f0f22b792a8613b8c31d28d Mon Sep 17 00:00:00 2001
+From: Cameron Katri <me@cameronkatri.com>
+Date: Thu, 20 May 2021 15:03:17 -0400
+Subject: [PATCH] acpiconf(8): Add libxo(3) support
+
+---
+ usr.sbin/acpi/acpiconf/Makefile | 2 +
+ usr.sbin/acpi/acpiconf/acpiconf.8 | 12 ++-
+ usr.sbin/acpi/acpiconf/acpiconf.c | 122 ++++++++++++++++--------------
+ 3 files changed, 80 insertions(+), 56 deletions(-)
+
+diff --git a/usr.sbin/acpi/acpiconf/Makefile b/usr.sbin/acpi/acpiconf/Makefile
+index 0bbadc1e8fb..479cf9563b2 100644
+--- a/usr.sbin/acpi/acpiconf/Makefile
++++ b/usr.sbin/acpi/acpiconf/Makefile
+@@ -5,4 +5,6 @@ PROG= acpiconf
+ MAN= acpiconf.8
+ WARNS?= 3
+
++LIBADD= xo
++
+ .include <bsd.prog.mk>
+diff --git a/usr.sbin/acpi/acpiconf/acpiconf.8 b/usr.sbin/acpi/acpiconf/acpiconf.8
+index 53888d8489e..7e4e7c9564c 100644
+--- a/usr.sbin/acpi/acpiconf/acpiconf.8
++++ b/usr.sbin/acpi/acpiconf/acpiconf.8
+@@ -27,7 +27,7 @@
+ .\"
+ .\" $FreeBSD$
+ .\"
+-.Dd December 27, 2018
++.Dd May 19, 2021
+ .Dt ACPICONF 8
+ .Os
+ .Sh NAME
+@@ -35,6 +35,7 @@
+ .Nd control ACPI power management
+ .Sh SYNOPSIS
+ .Nm
++.Op Fl -libxo
+ .Op Fl h
+ .Op Fl i Ar batt
+ .Op Fl k Ar ack
+@@ -46,6 +47,13 @@ utility allows the user control of the ACPI power management
+ functions.
+ The following command-line options are recognized:
+ .Bl -tag -width ".Fl s Ar type"
++.It Fl -libxo
++Generate output via
++.Xr libxo 3
++in a selection of different human and machine readable formats.
++See
++.Xr xo_parse_args 3
++for details on command line arguments.
+ .It Fl h
+ Displays a summary of available options.
+ .It Fl i Ar batt
+@@ -96,6 +104,8 @@ for more information about
+ .Va $local_startup .
+ .El
+ .Sh SEE ALSO
++.Xr libxo 3 ,
++.Xr xo_parse_args 3 ,
+ .Xr acpi 4 ,
+ .Xr acpidump 8 ,
+ .Xr apm 8 ,
+diff --git a/usr.sbin/acpi/acpiconf/acpiconf.c b/usr.sbin/acpi/acpiconf/acpiconf.c
+index 8a31657fb98..35c40ff1ab7 100644
+--- a/usr.sbin/acpi/acpiconf/acpiconf.c
++++ b/usr.sbin/acpi/acpiconf/acpiconf.c
+@@ -37,6 +37,7 @@
+ #include <sys/ioctl.h>
+ #include <sysexits.h>
+ #include <unistd.h>
++#include <libxo/xo.h>
+
+ #include <dev/acpica/acpiio.h>
+
+@@ -53,7 +54,7 @@ acpi_init(void)
+ if (acpifd == -1)
+ acpifd = open(ACPIDEV, O_RDONLY);
+ if (acpifd == -1)
+- err(EX_OSFILE, ACPIDEV);
++ xo_err(EX_OSFILE, ACPIDEV);
+ }
+
+ /* Prepare to sleep and then wait for the signal that sleeping can occur. */
+@@ -65,7 +66,7 @@ acpi_sleep(int sleep_type)
+ /* Notify OS that we want to sleep. devd(8) gets this notify. */
+ ret = ioctl(acpifd, ACPIIO_REQSLPSTATE, &sleep_type);
+ if (ret != 0)
+- err(EX_IOERR, "request sleep type (%d) failed", sleep_type);
++ xo_err(EX_IOERR, "request sleep type (%d) failed", sleep_type);
+ }
+
+ /* Ack or abort a pending suspend request. */
+@@ -76,7 +77,7 @@ acpi_sleep_ack(int err_val)
+
+ ret = ioctl(acpifd, ACPIIO_ACKSLPSTATE, &err_val);
+ if (ret != 0)
+- err(EX_IOERR, "ack sleep type failed");
++ xo_err(EX_IOERR, "ack sleep type failed");
+ }
+
+ /* should be a acpi define, but doesn't appear to be */
+@@ -92,78 +93,82 @@ acpi_battinfo(int num)
+ uint32_t volt;
+
+ if (num < 0 || num > 64)
+- errx(EX_USAGE, "invalid battery %d", num);
++ xo_errx(EX_USAGE, "invalid battery %d", num);
+
+ /* Print battery design information. */
+ battio.unit = num;
+ if (ioctl(acpifd, ACPIIO_BATT_GET_BIX, &battio) == -1)
+- err(EX_IOERR, "get battery info (%d) failed", num);
++ xo_err(EX_IOERR, "get battery info (%d) failed", num);
+ amp = battio.bix.units;
+ pwr_units = amp ? "mA" : "mW";
+ if (battio.bix.dcap == UNKNOWN_CAP)
+- printf("Design capacity:\tunknown\n");
++ xo_emit("{Lc:Design capacity}{P:\t}{:design-capacity/unknown}\n");
+ else
+- printf("Design capacity:\t%d %sh\n", battio.bix.dcap,
+- pwr_units);
++ xo_emit("{Lc:Design capacity}{P:\t}{:design-capacity/%d}{Uw:/%sh}\n",
++ battio.bix.dcap, pwr_units);
+ if (battio.bix.lfcap == UNKNOWN_CAP)
+- printf("Last full capacity:\tunknown\n");
++ xo_emit("{Lc:Last full capacity}{P:\t}{:last-full-capacity/unknown}\n");
+ else
+- printf("Last full capacity:\t%d %sh\n", battio.bix.lfcap,
+- pwr_units);
+- printf("Technology:\t\t%s\n", battio.bix.btech == 0 ?
++ xo_emit("{Lc:Last full capacity}{P:\t}{:last-full-capacity/%d}{Uw:/%sh}\n",
++ battio.bix.lfcap, pwr_units);
++ xo_emit("{Lc:Technology}{P:\t\t}{:technology}\n", battio.bix.btech == 0 ?
+ "primary (non-rechargeable)" : "secondary (rechargeable)");
+ if (ACPI_BIX_REV_MIN_CHECK(battio.bix.rev, ACPI_BIX_REV_1)) {
+- printf("Battery Swappable Capability:\t");
++ xo_emit("{Lc:Battery Swappable Capability}{P:\t}");
+ if (battio.bix.scap == ACPI_BIX_SCAP_NO)
+- printf("Non-swappable\n");
++ xo_emit("{:swappable/Non-swappable/no}\n");
+ else if (battio.bix.scap == ACPI_BIX_SCAP_COLD)
+- printf("cold swap\n");
++ xo_emit("{:swappable/cold swap/cold}\n");
+ else if (battio.bix.scap == ACPI_BIX_SCAP_HOT)
+- printf("hot swap\n");
++ xo_emit("{:swappable/hot swap/hot}\n");
+ else
+- printf("unknown\n");
++ xo_emit("{:swappable/unknown}\n");
+ }
+ if (battio.bix.dvol == UNKNOWN_CAP)
+- printf("Design voltage:\t\tunknown\n");
++ xo_emit("{Lc:Design voltage}{P:\t\t}{:voltage/unknown}\n");
+ else
+- printf("Design voltage:\t\t%d mV\n", battio.bix.dvol);
+- printf("Capacity (warn):\t%d %sh\n", battio.bix.wcap, pwr_units);
+- printf("Capacity (low):\t\t%d %sh\n", battio.bix.lcap, pwr_units);
++ xo_emit("{Lc:Design voltage}{P:\t\t}{:voltage/%d}{Uw:mV}\n", battio.bix.dvol);
++ xo_emit("{Lc:Capacity (warn)}{P:\t}{:warn-capacity/%d}{Uw:/%sh}\n",
++ battio.bix.wcap, pwr_units);
++ xo_emit("{Lc:Capacity (low)}{P:\t\t}{:low-capacity/%d}{Uw:/%sh}\n",
++ battio.bix.lcap, pwr_units);
+ if (ACPI_BIX_REV_MIN_CHECK(battio.bix.rev, ACPI_BIX_REV_0)) {
+ if (battio.bix.cycles != ACPI_BATT_UNKNOWN)
+- printf("Cycle Count:\t\t%d\n", battio.bix.cycles);
+- printf("Mesurement Accuracy:\t%d %%\n",
++ xo_emit("{Lc:Cycle Count}{P:\t\t}{:cycles/%d}\n", battio.bix.cycles);
++ xo_emit("{Lc:Mesurement Accuracy}{P:\t}{:accuracy/%d}{Uw:%%}\n",
+ battio.bix.accuracy / 1000);
+ if (battio.bix.stmax != ACPI_BATT_UNKNOWN)
+- printf("Max Sampling Time:\t%d ms\n",
++ xo_emit("{Lc:Max Sampling Time}{P:\t}{:sampling-max/%d}{Uw:ms}\n",
+ battio.bix.stmax);
+ if (battio.bix.stmin != ACPI_BATT_UNKNOWN)
+- printf("Min Sampling Time:\t%d ms\n",
++ xo_emit("{Lc:Min Sampling Time}{P:\t}{:sampling-min/%d}{Uw:ms}\n",
+ battio.bix.stmin);
+- printf("Max Average Interval:\t%d ms\n",
++ xo_emit("{Lc:Max Average Interval}{P:\t}{:avg-interval-max/%d}{Uw:ms}\n",
+ battio.bix.aimax);
+- printf("Min Average Interval:\t%d ms\n",
++ xo_emit("{Lc:Min Average Interval}{P:\t}{:avg-interval-min/%d}{Uw:ms}\n",
+ battio.bix.aimin);
+ }
+- printf("Low/warn granularity:\t%d %sh\n", battio.bix.gra1, pwr_units);
+- printf("Warn/full granularity:\t%d %sh\n", battio.bix.gra2, pwr_units);
+- printf("Model number:\t\t%s\n", battio.bix.model);
+- printf("Serial number:\t\t%s\n", battio.bix.serial);
+- printf("Type:\t\t\t%s\n", battio.bix.type);
+- printf("OEM info:\t\t%s\n", battio.bix.oeminfo);
++ xo_emit("Low/warn granularity:{P:\t}{:granularity-lw/%d}{Uw:/%sh}\n",
++ battio.bix.gra1, pwr_units);
++ xo_emit("Warn/full granularity:{P:\t}{:granularity-wf/%d}{Uw:/%sh}\n",
++ battio.bix.gra2, pwr_units);
++ xo_emit("{Lc:Model number}{P:\t\t}{:model}\n", battio.bix.model);
++ xo_emit("{Lc:Serial number}{P:\t\t}{:serial}\n", battio.bix.serial);
++ xo_emit("{Lc:Type}{P:\t\t\t}{:type}\n", battio.bix.type);
++ xo_emit("{Lc:OEM info}{P:\t\t}{:oeminfo}\n", battio.bix.oeminfo);
+
+ /* Fetch battery voltage information. */
+ volt = UNKNOWN_VOLTAGE;
+ battio.unit = num;
+ if (ioctl(acpifd, ACPIIO_BATT_GET_BST, &battio) == -1)
+- err(EX_IOERR, "get battery status (%d) failed", num);
++ xo_err(EX_IOERR, "get battery status (%d) failed", num);
+ if (battio.bst.state != ACPI_BATT_STAT_NOT_PRESENT)
+ volt = battio.bst.volt;
+
+ /* Print current battery state information. */
+ battio.unit = num;
+ if (ioctl(acpifd, ACPIIO_BATT_GET_BATTINFO, &battio) == -1)
+- err(EX_IOERR, "get battery user info (%d) failed", num);
++ xo_err(EX_IOERR, "get battery user info (%d) failed", num);
+ if (battio.battinfo.state != ACPI_BATT_STAT_NOT_PRESENT) {
+ const char *state;
+ switch (battio.battinfo.state & ACPI_BATT_STAT_BST_MASK) {
+@@ -188,36 +193,36 @@ acpi_battinfo(int num)
+ default:
+ state = "invalid";
+ }
+- printf("State:\t\t\t%s\n", state);
++ xo_emit("{Lc:State}{P:\t\t\t}{:state}\n", state);
+ if (battio.battinfo.cap == -1)
+- printf("Remaining capacity:\tunknown\n");
++ xo_emit("{Lc:Remaining capacity}{P:\t}{:remaining-capacity/unknown}\n");
+ else
+- printf("Remaining capacity:\t%d%%\n",
++ xo_emit("{Lc:Remaining capacity}{P:\t}{:remaining-capacity/%d}{D:%%}\n",
+ battio.battinfo.cap);
+ if (battio.battinfo.min == -1)
+- printf("Remaining time:\t\tunknown\n");
++ xo_emit("{Lc:Remaining time}{P:\t\t}{:remaining-time/unknown}\n");
+ else {
+ hours = battio.battinfo.min / 60;
+ min = battio.battinfo.min % 60;
+- printf("Remaining time:\t\t%d:%02d\n", hours, min);
++ xo_emit("{Lc:Remaining time}{P:\t\t}{:remaining-time/%d:%02d}\n", hours, min);
+ }
+ if (battio.battinfo.rate == -1)
+- printf("Present rate:\t\tunknown\n");
++ xo_emit("{Lc:Present rate}{P:\t\t}{:present-rate/unknown}\n");
+ else if (amp && volt != UNKNOWN_VOLTAGE) {
+- printf("Present rate:\t\t%d mA (%d mW)\n",
++ xo_emit("{Lc:Present rate}{P:\t\t}{:present-rate/%d}{Uw:mA} {D:(}{:present-rate-mw/%d}{Uw:mW}{D:)}\n",
+ battio.battinfo.rate,
+ battio.battinfo.rate * volt / 1000);
+ } else
+- printf("Present rate:\t\t%d %s\n",
++ xo_emit("{Lc:Present rate}{P:\t\t}{:present-rate/%d}{Uw:/%s}\n",
+ battio.battinfo.rate, pwr_units);
+ } else
+- printf("State:\t\t\tnot present\n");
++ xo_emit("{Lc:State}{P:\t\t\t}{:state/not present}\n");
+
+ /* Print battery voltage information. */
+ if (volt == UNKNOWN_VOLTAGE)
+- printf("Present voltage:\tunknown\n");
++ xo_emit("{Lc:Present voltage}{P:\t}{q:present-voltage/unknown}\n");
+ else
+- printf("Present voltage:\t%d mV\n", volt);
++ xo_emit("{Lc:Present voltage}{P:\t}{q:present-voltage/%d}{Uw:mV}\n", volt);
+
+ return (0);
+ }
+@@ -225,7 +230,9 @@ acpi_battinfo(int num)
+ static void
+ usage(const char* prog)
+ {
+- printf("usage: %s [-h] [-i batt] [-k ack] [-s 1-4]\n", prog);
++ xo_error("usage: %s [-h] [-i batt] [-k ack] [-s 1-4]\n", prog);
++ xo_close_container("acpiconf");
++ xo_finish();
+ exit(0);
+ }
+
+@@ -237,6 +244,9 @@ main(int argc, char *argv[])
+ int iflag = 0, kflag = 0, sflag = 0;
+
+ prog = argv[0];
++
++ argc = xo_parse_args(argc, argv);
++ xo_open_container("acpiconf");
+ if (argc < 2)
+ usage(prog);
+ /* NOTREACHED */
+@@ -249,13 +259,13 @@ main(int argc, char *argv[])
+ iflag = 1;
+ battery = strtol(optarg, &end, 10);
+ if ((size_t)(end - optarg) != strlen(optarg))
+- errx(EX_USAGE, "invalid battery");
++ xo_errx(EX_USAGE, "invalid battery");
+ break;
+ case 'k':
+ kflag = 1;
+ ack = strtol(optarg, &end, 10);
+ if ((size_t)(end - optarg) != strlen(optarg))
+- errx(EX_USAGE, "invalid ack argument");
++ xo_errx(EX_USAGE, "invalid ack argument");
+ break;
+ case 's':
+ sflag = 1;
+@@ -263,9 +273,9 @@ main(int argc, char *argv[])
+ optarg++;
+ sleep_type = strtol(optarg, &end, 10);
+ if ((size_t)(end - optarg) != strlen(optarg))
+- errx(EX_USAGE, "invalid sleep type");
++ xo_errx(EX_USAGE, "invalid sleep type");
+ if (sleep_type < 1 || sleep_type > 4)
+- errx(EX_USAGE, "invalid sleep type (%d)",
++ xo_errx(EX_USAGE, "invalid sleep type (%d)",
+ sleep_type);
+ break;
+ case 'h':
+@@ -278,19 +288,19 @@ main(int argc, char *argv[])
+ argv += optind;
+
+ if (iflag != 0 && kflag != 0 && sflag != 0)
+- errx(EX_USAGE, "-i, -k and -s are mutually exclusive");
++ xo_errx(EX_USAGE, "-i, -k and -s are mutually exclusive");
+
+ if (iflag != 0) {
+ if (kflag != 0)
+- errx(EX_USAGE, "-i and -k are mutually exclusive");
++ xo_errx(EX_USAGE, "-i and -k are mutually exclusive");
+ if (sflag != 0)
+- errx(EX_USAGE, "-i and -s are mutually exclusive");
++ xo_errx(EX_USAGE, "-i and -s are mutually exclusive");
+ acpi_battinfo(battery);
+ }
+
+ if (kflag != 0) {
+ if (sflag != 0)
+- errx(EX_USAGE, "-k and -s are mutually exclusive");
++ xo_errx(EX_USAGE, "-k and -s are mutually exclusive");
+ acpi_sleep_ack(ack);
+ }
+
+@@ -299,5 +309,7 @@ main(int argc, char *argv[])
+ acpi_sleep(sleep_type);
+
+ close(acpifd);
++ xo_close_container("acpiconf");
++ xo_finish();
+ exit (0);
+ }
+--
+2.31.1
+
diff --git a/diff-1-Add-color-support.patch b/diff-1-Add-color-support.patch
new file mode 100644
index 0000000..31b1fde
--- /dev/null
+++ b/diff-1-Add-color-support.patch
@@ -0,0 +1,238 @@
+From 392ea394e6ae7fe34aed7b0b98ab4d47b3652df2 Mon Sep 17 00:00:00 2001
+From: Cameron Katri <me@cameronkatri.com>
+Date: Fri, 28 May 2021 15:21:45 -0400
+Subject: [PATCH] diff(1): Add --color support
+
+---
+ usr.bin/diff/diff.1 | 17 +++++++++++++++++
+ usr.bin/diff/diff.c | 39 ++++++++++++++++++++++++++++++++++++++-
+ usr.bin/diff/diff.h | 3 ++-
+ usr.bin/diff/diffreg.c | 16 ++++++++++++++++
+ 4 files changed, 73 insertions(+), 2 deletions(-)
+
+diff --git a/usr.bin/diff/diff.1 b/usr.bin/diff/diff.1
+index e0a790f6efb..50fd43902d5 100644
+--- a/usr.bin/diff/diff.1
++++ b/usr.bin/diff/diff.1
+@@ -44,6 +44,7 @@
+ .Fl n | q | u | y
+ .Oc
+ .Op Fl -brief
++.Op Fl -color Ns = Ns Ar when
+ .Op Fl -changed-group-format Ar GFMT
+ .Op Fl -ed
+ .Op Fl -expand-tabs
+@@ -71,6 +72,7 @@
+ .Op Fl I Ar pattern | Fl -ignore-matching-lines Ar pattern
+ .Op Fl L Ar label | Fl -label Ar label
+ .Op Fl -brief
++.Op Fl -color Ns = Ns Ar when
+ .Op Fl -changed-group-format Ar GFMT
+ .Op Fl -ed
+ .Op Fl -expand-tabs
+@@ -96,6 +98,7 @@
+ .Op Fl aBbdiltw
+ .Op Fl I Ar pattern | Fl -ignore-matching-lines Ar pattern
+ .Op Fl -brief
++.Op Fl -color Ns = Ns Ar when
+ .Op Fl -changed-group-format Ar GFMT
+ .Op Fl -ed
+ .Op Fl -expand-tabs
+@@ -122,6 +125,7 @@
+ .Op Fl I Ar pattern | Fl -ignore-matching-lines Ar pattern
+ .Op Fl L Ar label | Fl -label Ar label
+ .Op Fl -brief
++.Op Fl -color Ns = Ns Ar when
+ .Op Fl -changed-group-format Ar GFMT
+ .Op Fl -ed
+ .Op Fl -expand-tabs
+@@ -150,6 +154,7 @@
+ .Fl n | q | u
+ .Oc
+ .Op Fl -brief
++.Op Fl -color Ns = Ns Ar when
+ .Op Fl -changed-group-format Ar GFMT
+ .Op Fl -context
+ .Op Fl -ed
+@@ -184,6 +189,7 @@
+ .Ar dir1 dir2
+ .Nm diff
+ .Op Fl aBbditwW
++.Op Fl -color Ns = Ns Ar when
+ .Op Fl -expand-tabs
+ .Op Fl -ignore-all-blanks
+ .Op Fl -ignore-blank-lines
+@@ -332,6 +338,17 @@ Causes chunks that include only blank lines to be ignored.
+ .It Fl b -ignore-space-change
+ Causes trailing blanks (spaces and tabs) to be ignored, and other
+ strings of blanks to compare equal.
++.It Fl Fl color= Ns Oo Ar when Oc
++Mark up the matching text with the expression stored in the
++.Ev DIFFCOLOR
++environment variable.
++The possible values of
++.Ar when
++are
++.Dq Cm never ,
++.Dq Cm always
++and
++.Dq Cm auto .
+ .It Fl d -minimal
+ Try very hard to produce a diff as small as possible.
+ This may consume a lot of processing power and memory when processing
+diff --git a/usr.bin/diff/diff.c b/usr.bin/diff/diff.c
+index 1bad6226f49..5204f85ed1c 100644
+--- a/usr.bin/diff/diff.c
++++ b/usr.bin/diff/diff.c
+@@ -38,11 +38,12 @@ __FBSDID("$FreeBSD$");
+ #include "diff.h"
+ #include "xmalloc.h"
+
+-int lflag, Nflag, Pflag, rflag, sflag, Tflag, cflag, Wflag;
++int lflag, Nflag, Pflag, rflag, sflag, Tflag, cflag, Wflag, colorflag = 0;
+ int diff_format, diff_context, status, ignore_file_case, suppress_common;
+ int tabsize = 8, width = 130;
+ char *start, *ifdefname, *diffargs, *label[2], *ignore_pats;
+ char *group_format = NULL;
++const char *add_code, *del_code;
+ struct stat stb1, stb2;
+ struct excludes *excludes_list;
+ regex_t ignore_re;
+@@ -57,6 +58,7 @@ enum {
+ OPT_HORIZON_LINES,
+ OPT_CHANGED_GROUP_FORMAT,
+ OPT_SUPPRESS_COMMON,
++ OPT_COLOR,
+ };
+
+ static struct option longopts[] = {
+@@ -97,6 +99,7 @@ static struct option longopts[] = {
+ { "tabsize", required_argument, NULL, OPT_TSIZE },
+ { "changed-group-format", required_argument, NULL, OPT_CHANGED_GROUP_FORMAT},
+ { "suppress-common-lines", no_argument, NULL, OPT_SUPPRESS_COMMON },
++ { "color", optional_argument, NULL, OPT_COLOR },
+ { NULL, 0, 0, '\0'}
+ };
+
+@@ -106,6 +109,7 @@ void push_excludes(char *);
+ void push_ignore_pats(char *);
+ void read_excludes_file(char *file);
+ void set_argstr(char **, char **);
++static const char *init_code(int, const char *);
+
+ int
+ main(int argc, char **argv)
+@@ -301,6 +305,21 @@ main(int argc, char **argv)
+ case OPT_SUPPRESS_COMMON:
+ suppress_common = 1;
+ break;
++ case OPT_COLOR:
++ if (optarg == NULL || strncmp(optarg, "auto", 4) == 0)
++ colorflag = isatty(STDOUT_FILENO) ? 1 : 0;
++ else if (strncmp(optarg, "always", 6) == 0)
++ colorflag = 1;
++ else if (strncmp(optarg, "never", 5) == 0)
++ colorflag = 0;
++ else
++ errx(2, "unsupported --color value '%s' (must be always, auto, or never)",
++ optarg);
++ if (colorflag) {
++ add_code = init_code(1, "32");
++ del_code = init_code(2, "31");
++ }
++ break;
+ default:
+ usage();
+ break;
+@@ -550,3 +569,21 @@ conflicting_format(void)
+ fprintf(stderr, "error: conflicting output format options.\n");
+ usage();
+ }
++
++static const char *
++init_code(int i, const char *rv)
++{
++ char *buf, *p, *env;
++ int j;
++
++ env = getenv("DIFFCOLORS");
++ if (env != NULL && *env != '\0') {
++ p = strdup(env);
++ for (j = 0; j < i; j++)
++ buf = strsep(&p, ":");
++ free(p);
++ if (buf != NULL)
++ return buf;
++ }
++ return rv;
++}
+diff --git a/usr.bin/diff/diff.h b/usr.bin/diff/diff.h
+index b5536bd7bf7..0c325d004b8 100644
+--- a/usr.bin/diff/diff.h
++++ b/usr.bin/diff/diff.h
+@@ -90,12 +90,13 @@ struct excludes {
+ struct excludes *next;
+ };
+
+-extern int lflag, Nflag, Pflag, rflag, sflag, Tflag, cflag, Wflag;
++extern int lflag, Nflag, Pflag, rflag, sflag, Tflag, cflag, Wflag, colorflag;
+ extern int diff_format, diff_context, status, ignore_file_case;
+ extern int suppress_common;
+ extern int tabsize, width;
+ extern char *start, *ifdefname, *diffargs, *label[2], *ignore_pats;
+ extern char *group_format;
++extern const char *add_code, *del_code;
+ extern struct stat stb1, stb2;
+ extern struct excludes *excludes_list;
+ extern regex_t ignore_re;
+diff --git a/usr.bin/diff/diffreg.c b/usr.bin/diff/diffreg.c
+index 1b28281024c..6b01af67a82 100644
+--- a/usr.bin/diff/diffreg.c
++++ b/usr.bin/diff/diffreg.c
+@@ -1183,13 +1183,23 @@ change(char *file1, FILE *f1, char *file2, FILE *f2, int a, int b, int c, int d,
+ }
+ }
+ if (diff_format == D_SIDEBYSIDE) {
++ if (colorflag && (a>b))
++ printf("\033[%sm", add_code);
++ else if (colorflag && (c>d))
++ printf("\033[%sm", del_code);
+ if (a > b) {
+ print_space(0, hw + padding , *pflags);
+ } else {
+ nc = fetch(ixold, a, b, f1, '\0', 1, *pflags);
+ print_space(nc, hw - nc + padding, *pflags);
+ }
++ if (colorflag && (a>b))
++ printf("\033[%sm", add_code);
++ else if (colorflag && (c>d))
++ printf("\033[%sm", del_code);
+ printf("%c", (a>b)? '>' : ((c>d)? '<' : '|'));
++ if (colorflag && (c>d))
++ printf("\33[m");
+ print_space(hw + padding + 1 , padding, *pflags);
+ fetch(ixnew, c, d, f2, '\0', 0, *pflags);
+ printf("\n");
+@@ -1263,6 +1273,10 @@ fetch(long *f, int a, int b, FILE *lb, int ch, int oldfile, int flags)
+ nc = hw;
+ if ((diff_format != D_IFDEF && diff_format != D_GFORMAT) &&
+ ch != '\0') {
++ if (colorflag && (ch == '>' || ch == '+'))
++ printf("\033[%sm", add_code);
++ else if (colorflag && (ch == '<' || ch == '-'))
++ printf("\033[%sm", del_code);
+ printf("%c", ch);
+ if (Tflag && (diff_format == D_NORMAL ||
+ diff_format == D_CONTEXT ||
+@@ -1335,6 +1349,8 @@ fetch(long *f, int a, int b, FILE *lb, int ch, int oldfile, int flags)
+ }
+ }
+ }
++ if (colorflag)
++ printf("\33[m");
+ return col;
+ }
+
+--
+2.31.1
+
diff --git a/ls-1-Allow-LSCOLORS-to-specify-an-underline.patch b/ls-1-Allow-LSCOLORS-to-specify-an-underline.patch
new file mode 100644
index 0000000..095d6f3
--- /dev/null
+++ b/ls-1-Allow-LSCOLORS-to-specify-an-underline.patch
@@ -0,0 +1,152 @@
+From f873a0a04c981fbcc7879bcefe355fbbfd1a8adb Mon Sep 17 00:00:00 2001
+From: Cameron Katri <me@cameronkatri.com>
+Date: Fri, 28 May 2021 17:56:48 -0400
+Subject: [PATCH] ls(1): Allow LSCOLORS to specify an underline
+
+Summary: Allows capitalizing the background color character to unable an underline instead of bold, capitalizing the foreground color char will still do bold.
+
+Differential Revision: https://reviews.freebsd.org/D30547
+---
+ bin/ls/extern.h | 1 +
+ bin/ls/ls.1 | 19 +++++++++++--------
+ bin/ls/ls.c | 2 ++
+ bin/ls/print.c | 16 ++++++++++++++--
+ 4 files changed, 28 insertions(+), 10 deletions(-)
+
+diff --git a/bin/ls/extern.h b/bin/ls/extern.h
+index 8dab2bcc9d8..247c2c4a1d5 100644
+--- a/bin/ls/extern.h
++++ b/bin/ls/extern.h
+@@ -66,6 +66,7 @@ extern char *ansi_bgcol;
+ extern char *ansi_coloff;
+ extern char *attrs_off;
+ extern char *enter_bold;
++extern char *enter_underline;
+
+ extern int colorflag;
+ extern bool explicitansi;
+diff --git a/bin/ls/ls.1 b/bin/ls/ls.1
+index 8510ca609cd..ef412dd2927 100644
+--- a/bin/ls/ls.1
++++ b/bin/ls/ls.1
+@@ -740,6 +740,7 @@ where
+ is the foreground color and
+ .Ar b
+ is the background color.
++When the background color is capitalized, the text will underlined.
+ .Pp
+ The color designators are as follows:
+ .Pp
+@@ -761,23 +762,25 @@ cyan
+ .It Sy h
+ light grey
+ .It Sy A
+-bold black, usually shows up as dark grey
++bold or underlined black, usually shows up as dark grey
+ .It Sy B
+-bold red
++bold or underlined red
+ .It Sy C
+-bold green
++bold or underlined green
+ .It Sy D
+-bold brown, usually shows up as yellow
++bold or underlined brown, usually shows up as yellow
+ .It Sy E
+-bold blue
++bold or underlined blue
+ .It Sy F
+-bold magenta
++bold or underlined magenta
+ .It Sy G
+-bold cyan
++bold or underlined cyan
+ .It Sy H
+-bold light grey; looks like bright white
++bold or underlined light grey; looks like bright white
+ .It Sy x
+ default foreground or background
++.It Sy X
++default foreground or background, with an underline or bold
+ .El
+ .Pp
+ Note that the above are standard
+diff --git a/bin/ls/ls.c b/bin/ls/ls.c
+index 338b3d1d2a2..67cb91fdcde 100644
+--- a/bin/ls/ls.c
++++ b/bin/ls/ls.c
+@@ -161,6 +161,7 @@ char *ansi_fgcol; /* ANSI sequence to set foreground colour */
+ char *ansi_coloff; /* ANSI sequence to reset colours */
+ char *attrs_off; /* ANSI sequence to turn off attributes */
+ char *enter_bold; /* ANSI sequence to set color to bold mode */
++char *enter_underline; /* ANSI sequence to enter underline mode */
+ #endif
+
+ static int rval;
+@@ -485,6 +486,7 @@ main(int argc, char *argv[])
+ ansi_bgcol = tgetstr("AB", &bp);
+ attrs_off = tgetstr("me", &bp);
+ enter_bold = tgetstr("md", &bp);
++ enter_underline = tgetstr("us", &bp);
+
+ /* To switch colours off use 'op' if
+ * available, otherwise use 'oc', or
+diff --git a/bin/ls/print.c b/bin/ls/print.c
+index 9a537418f7b..da92668d5c5 100644
+--- a/bin/ls/print.c
++++ b/bin/ls/print.c
+@@ -107,6 +107,7 @@ static const char *defcolors = "exfxcxdxbxegedabagacad";
+ static struct {
+ int num[2];
+ int bold;
++ int underline;
+ } colors[C_NUMCOLORS];
+ #endif
+
+@@ -548,6 +549,8 @@ printcolor_termcap(Colors c)
+
+ if (colors[c].bold)
+ tputs(enter_bold, 1, putch);
++ if (colors[c].underline)
++ tputs(enter_underline, 1, putch);
+
+ if (colors[c].num[0] != -1) {
+ ansiseq = tgoto(ansi_fgcol, 0, colors[c].num[0]);
+@@ -569,6 +572,8 @@ printcolor_ansi(Colors c)
+
+ if (colors[c].bold)
+ printf("1");
++ if (colors[c].underline)
++ printf(";4");
+ if (colors[c].num[0] != -1)
+ printf(";3%d", colors[c].num[0]);
+ if (colors[c].num[1] != -1)
+@@ -667,6 +672,7 @@ parsecolors(const char *cs)
+ len = strlen(cs);
+ for (i = 0; i < (int)C_NUMCOLORS; i++) {
+ colors[i].bold = 0;
++ colors[i].underline = 0;
+
+ if (len <= 2 * (size_t)i) {
+ c[0] = defcolors[2 * i];
+@@ -689,9 +695,15 @@ parsecolors(const char *cs)
+ colors[i].num[j] = c[j] - 'a';
+ else if (c[j] >= 'A' && c[j] <= 'H') {
+ colors[i].num[j] = c[j] - 'A';
+- colors[i].bold = 1;
+- } else if (tolower((unsigned char)c[j]) == 'x')
++ if (j)
++ colors[i].underline = 1;
++ else
++ colors[i].bold = 1;
++ } else if (tolower((unsigned char)c[j]) == 'x') {
++ if (j && c[j] == 'X')
++ colors[i].underline = 1;
+ colors[i].num[j] = -1;
++ }
+ else {
+ warnx("invalid character '%c' in LSCOLORS"
+ " env var", c[j]);
+--
+2.31.1
+
diff --git a/mount-8-Add-libxo-3-support.patch b/mount-8-Add-libxo-3-support.patch
new file mode 100644
index 0000000..353a758
--- /dev/null
+++ b/mount-8-Add-libxo-3-support.patch
@@ -0,0 +1,475 @@
+From 9d8571e84bf2c006b5053a776358c148b641a48f Mon Sep 17 00:00:00 2001
+From: Cameron Katri <me@cameronkatri.com>
+Date: Thu, 20 May 2021 15:04:10 -0400
+Subject: [PATCH] mount(8): Add libxo(3) support
+
+---
+ sbin/mount/Makefile | 2 +-
+ sbin/mount/mount.8 | 14 ++++-
+ sbin/mount/mount.c | 150 ++++++++++++++++++++++++++++----------------
+ 3 files changed, 111 insertions(+), 55 deletions(-)
+
+diff --git a/sbin/mount/Makefile b/sbin/mount/Makefile
+index 68c7ee9819d..34ba498a2a3 100644
+--- a/sbin/mount/Makefile
++++ b/sbin/mount/Makefile
+@@ -7,6 +7,6 @@ SRCS= mount.c mount_fs.c getmntopts.c vfslist.c
+ MAN= mount.8
+ # We do NOT install the getmntopts.3 man page.
+
+-LIBADD= util
++LIBADD= util xo
+
+ .include <bsd.prog.mk>
+diff --git a/sbin/mount/mount.8 b/sbin/mount/mount.8
+index 3aee1bb8615..59a0f6bb032 100644
+--- a/sbin/mount/mount.8
++++ b/sbin/mount/mount.8
+@@ -28,7 +28,7 @@
+ .\" @(#)mount.8 8.8 (Berkeley) 6/16/94
+ .\" $FreeBSD$
+ .\"
+-.Dd August 28, 2019
++.Dd May 18, 2021
+ .Dt MOUNT 8
+ .Os
+ .Sh NAME
+@@ -36,14 +36,17 @@
+ .Nd mount file systems
+ .Sh SYNOPSIS
+ .Nm
++.Op Fl -libxo
+ .Op Fl adflpruvw
+ .Op Fl F Ar fstab
+ .Op Fl o Ar options
+ .Op Fl t Oo Cm no Oc Ns Cm Ar type Ns Op Cm , Ns Ar type ...
+ .Nm
++.Op Fl -libxo
+ .Op Fl dfpruvw
+ .Ar special | node
+ .Nm
++.Op Fl -libxo
+ .Op Fl dfpruvw
+ .Op Fl o Ar options
+ .Op Fl t Oo Cm no Oc Ns Cm Ar type Ns Op Cm , Ns Ar type ...
+@@ -72,6 +75,13 @@ this list is printed.
+ .Pp
+ The options are as follows:
+ .Bl -tag -width indent
++.It Fl -libxo
++Generate output via
++.Xr libxo 3
++in a selection of different human and machine readable formats.
++See
++.Xr xo_parse_args 3
++for details on command line arguments.
+ .It Fl a
+ All the file systems described in
+ .Xr fstab 5
+@@ -552,6 +562,8 @@ support for a particular file system might be provided either on a static
+ .Xr setfacl 1 ,
+ .Xr nmount 2 ,
+ .Xr acl 3 ,
++.Xr libxo 3 ,
++.Xr xo_parse_args 3 ,
+ .Xr mac 4 ,
+ .Xr cd9660 5 ,
+ .Xr devfs 5 ,
+diff --git a/sbin/mount/mount.c b/sbin/mount/mount.c
+index fad999c97dc..de30dd39afe 100644
+--- a/sbin/mount/mount.c
++++ b/sbin/mount/mount.c
+@@ -60,11 +60,18 @@ __FBSDID("$FreeBSD$");
+ #include <string.h>
+ #include <unistd.h>
+ #include <libutil.h>
++#include <libxo/xo.h>
+
+ #include "extern.h"
+ #include "mntopts.h"
+ #include "pathnames.h"
+
++#define EXIT(a) { \
++ xo_close_container("mount"); \
++ xo_finish(); \
++ exit(a); \
++ }
++
+ /* `meta' options */
+ #define MOUNT_META_OPTION_FSTAB "fstab"
+ #define MOUNT_META_OPTION_CURRENT "current"
+@@ -146,21 +153,21 @@ exec_mountprog(const char *name, const char *execname, char *const argv[])
+
+ switch (pid = fork()) {
+ case -1: /* Error. */
+- warn("fork");
+- exit (1);
++ xo_warn("fork");
++ EXIT(1);
+ case 0: /* Child. */
+ /* Go find an executable. */
+ execvP(execname, _PATH_SYSPATH, argv);
+ if (errno == ENOENT) {
+- warn("exec %s not found", execname);
++ xo_warn("exec %s not found", execname);
+ if (execname[0] != '/') {
+- warnx("in path: %s", _PATH_SYSPATH);
++ xo_warnx("in path: %s", _PATH_SYSPATH);
+ }
+ }
+- exit(1);
++ EXIT(1);
+ default: /* Parent. */
+ if (waitpid(pid, &status, 0) < 0) {
+- warn("waitpid");
++ xo_warn("waitpid");
+ return (1);
+ }
+
+@@ -168,7 +175,7 @@ exec_mountprog(const char *name, const char *execname, char *const argv[])
+ if (WEXITSTATUS(status) != 0)
+ return (WEXITSTATUS(status));
+ } else if (WIFSIGNALED(status)) {
+- warnx("%s: %s", name, sys_siglist[WTERMSIG(status)]);
++ xo_warnx("%s: %s", name, sys_siglist[WTERMSIG(status)]);
+ return (1);
+ }
+ break;
+@@ -185,7 +192,7 @@ specified_ro(const char *arg)
+
+ optbuf = strdup(arg);
+ if (optbuf == NULL)
+- err(1, NULL);
++ xo_err(1, NULL);
+
+ for (opt = optbuf; (opt = strtok(opt, ",")) != NULL; opt = NULL) {
+ if (strcmp(opt, "ro") == 0) {
+@@ -220,13 +227,13 @@ restart_mountd(void)
+ * happened due to the bugs in pidfile(3).
+ */
+ if (mountdpid <= 0) {
+- warnx("mountd pid %d, refusing to send SIGHUP", mountdpid);
++ xo_warnx("mountd pid %d, refusing to send SIGHUP", mountdpid);
+ return;
+ }
+
+ /* We have mountd(8) PID in mountdpid varible, let's signal it. */
+ if (kill(mountdpid, SIGHUP) == -1)
+- err(1, "signal mountd");
++ xo_err(1, "signal mountd");
+ }
+
+ int
+@@ -244,6 +251,12 @@ main(int argc, char *argv[])
+ options = NULL;
+ vfslist = NULL;
+ vfstype = "ufs";
++
++ argc = xo_parse_args(argc, argv);
++ if (argc < 0)
++ return (argc);
++ xo_open_container("mount");
++
+ while ((ch = getopt(argc, argv, "adF:fLlno:prt:uvw")) != -1)
+ switch (ch) {
+ case 'a':
+@@ -285,7 +298,7 @@ main(int argc, char *argv[])
+ break;
+ case 't':
+ if (vfslist != NULL)
+- errx(1, "only one -t option may be specified");
++ xo_errx(1, "only one -t option may be specified");
+ vfslist = makevfslist(optarg);
+ vfstype = optarg;
+ break;
+@@ -318,7 +331,7 @@ main(int argc, char *argv[])
+ case 0:
+ if ((mntsize = getmntinfo(&mntbuf,
+ verbose ? MNT_WAIT : MNT_NOWAIT)) == 0)
+- err(1, "getmntinfo");
++ xo_err(1, "getmntinfo");
+ if (all) {
+ while ((fs = getfsent()) != NULL) {
+ if (BADTYPE(fs->fs_type))
+@@ -347,12 +360,17 @@ main(int argc, char *argv[])
+ rval = 1;
+ }
+ } else if (fstab_style) {
++ xo_open_list("fstab");
+ for (i = 0; i < mntsize; i++) {
+ if (checkvfsname(mntbuf[i].f_fstypename, vfslist))
+ continue;
++ xo_open_instance("fstab");
+ putfsent(&mntbuf[i]);
++ xo_close_instance("fstab");
+ }
++ xo_close_list("fstab");
+ } else {
++ xo_open_list("mounted");
+ for (i = 0; i < mntsize; i++) {
+ if (checkvfsname(mntbuf[i].f_fstypename,
+ vfslist))
+@@ -360,10 +378,13 @@ main(int argc, char *argv[])
+ if (!verbose &&
+ (mntbuf[i].f_flags & MNT_IGNORE) != 0)
+ continue;
++ xo_open_instance("mounted");
+ prmount(&mntbuf[i]);
++ xo_close_instance("mounted");
+ }
++ xo_close_list("mounted");
+ }
+- exit(rval);
++ EXIT(rval);
+ case 1:
+ if (vfslist != NULL)
+ usage();
+@@ -373,7 +394,7 @@ main(int argc, char *argv[])
+ mntfromname = NULL;
+ have_fstab = 0;
+ if ((mntbuf = getmntpt(*argv)) == NULL)
+- errx(1, "not currently mounted %s", *argv);
++ xo_errx(1, "not currently mounted %s", *argv);
+ /*
+ * Only get the mntflags from fstab if both mntpoint
+ * and mntspec are identical. Also handle the special
+@@ -411,10 +432,10 @@ main(int argc, char *argv[])
+ }
+ if ((fs = getfsfile(*argv)) == NULL &&
+ (fs = getfsspec(*argv)) == NULL)
+- errx(1, "%s: unknown special file or file system",
++ xo_errx(1, "%s: unknown special file or file system",
+ *argv);
+ if (BADTYPE(fs->fs_type))
+- errx(1, "%s has unknown file system type",
++ xo_errx(1, "%s has unknown file system type",
+ *argv);
+ rval = mountfs(fs->fs_vfstype, fs->fs_spec, fs->fs_file,
+ init_flags, options, fs->fs_mntops);
+@@ -460,7 +481,7 @@ main(int argc, char *argv[])
+ if (rval == 0 && getuid() == 0)
+ restart_mountd();
+
+- exit(rval);
++ EXIT(rval);
+ }
+
+ int
+@@ -537,7 +558,7 @@ append_arg(struct cpa *sa, char *arg)
+ sa->sz = sa->sz == 0 ? 8 : sa->sz * 2;
+ sa->a = realloc(sa->a, sizeof(*sa->a) * sa->sz);
+ if (sa->a == NULL)
+- errx(1, "realloc failed");
++ xo_errx(1, "realloc failed");
+ }
+ sa->a[++sa->c] = arg;
+ }
+@@ -553,7 +574,7 @@ mountfs(const char *vfstype, const char *spec, const char *name, int flags,
+
+ /* resolve the mountpoint with realpath(3) */
+ if (checkpath(name, mntpath) != 0) {
+- warn("%s", mntpath);
++ xo_warn("%s", mntpath);
+ return (1);
+ }
+ name = mntpath;
+@@ -596,12 +617,12 @@ mountfs(const char *vfstype, const char *spec, const char *name, int flags,
+
+ if (debug) {
+ if (use_mountprog(vfstype))
+- printf("exec: %s", execname);
++ xo_emit("{Lwc:exec}{:execname/%s}", execname);
+ else
+- printf("mount -t %s", vfstype);
++ xo_emit("{:execname/mount}{P: }{l:opts/-t}{P: }{l:opts/%s}", vfstype);
+ for (i = 1; i < mnt_argv.c; i++)
+- (void)printf(" %s", mnt_argv.a[i]);
+- (void)printf("\n");
++ xo_emit("{P: }{l:opts}", mnt_argv.a[i]);
++ xo_emit("\n");
+ free(optbuf);
+ free(mountprog);
+ mountprog = NULL;
+@@ -620,13 +641,22 @@ mountfs(const char *vfstype, const char *spec, const char *name, int flags,
+
+ if (verbose) {
+ if (statfs(name, &sf) < 0) {
+- warn("statfs %s", name);
++ xo_warn("statfs %s", name);
+ return (1);
+ }
+- if (fstab_style)
++ if (fstab_style) {
++ xo_open_list("fstab");
++ xo_open_instance("fstab");
+ putfsent(&sf);
+- else
++ xo_close_instance("fstab");
++ xo_close_list("fstab");
++ } else {
++ xo_open_list("mounted");
++ xo_open_instance("mounted");
+ prmount(&sf);
++ xo_close_instance("mounted");
++ xo_close_list("mounted");
++ }
+ }
+
+ return (ret);
+@@ -639,14 +669,15 @@ prmount(struct statfs *sfp)
+ unsigned int i;
+ struct mntoptnames *o;
+ struct passwd *pw;
++ char *fsidbuf;
+
+- (void)printf("%s on %s (%s", sfp->f_mntfromname, sfp->f_mntonname,
+- sfp->f_fstypename);
++ xo_emit("{:special}{L: on }{:node}{L: (}{:fstype}", sfp->f_mntfromname,
++ sfp->f_mntonname, sfp->f_fstypename);
+
+ flags = sfp->f_flags & MNT_VISFLAGMASK;
+ for (o = optnames; flags != 0 && o->o_opt != 0; o++)
+ if (flags & o->o_opt) {
+- (void)printf(", %s", o->o_name);
++ xo_emit("{D:, }{l:opts}", o->o_name);
+ flags &= ~o->o_opt;
+ }
+ /*
+@@ -654,28 +685,37 @@ prmount(struct statfs *sfp)
+ * or privileged non-root user.
+ */
+ if ((flags & MNT_USER) != 0 || sfp->f_owner != 0) {
+- (void)printf(", mounted by ");
++ xo_emit("{D:, }{L:mounted by }");
+ if ((pw = getpwuid(sfp->f_owner)) != NULL)
+- (void)printf("%s", pw->pw_name);
++ xo_emit("{:mounter}", pw->pw_name);
+ else
+- (void)printf("%d", sfp->f_owner);
++ xo_emit("{:mounter}", sfp->f_owner);
+ }
+ if (verbose) {
+- if (sfp->f_syncwrites != 0 || sfp->f_asyncwrites != 0)
+- (void)printf(", writes: sync %ju async %ju",
++ if (sfp->f_syncwrites != 0 || sfp->f_asyncwrites != 0) {
++ xo_open_container("writes");
++ xo_emit("{D:, }{Lwc:writes}{Lw:sync}{w:sync/%ju}{Lw:async}{:async/%ju}",
+ (uintmax_t)sfp->f_syncwrites,
+ (uintmax_t)sfp->f_asyncwrites);
+- if (sfp->f_syncreads != 0 || sfp->f_asyncreads != 0)
+- (void)printf(", reads: sync %ju async %ju",
++ xo_close_container("writes");
++ }
++ if (sfp->f_syncreads != 0 || sfp->f_asyncreads != 0) {
++ xo_open_container("reads");
++ xo_emit("{D:, }{Lwc:reads}{Lw:sync}{w:sync/%ju}{Lw:async}{:async/%ju}",
+ (uintmax_t)sfp->f_syncreads,
+ (uintmax_t)sfp->f_asyncreads);
++ xo_close_container("reads");
++ }
+ if (sfp->f_fsid.val[0] != 0 || sfp->f_fsid.val[1] != 0) {
+- (void)printf(", fsid ");
++ xo_emit("{D:, }{Lw:fsid}");
++ fsidbuf = strdup("");
+ for (i = 0; i < sizeof(sfp->f_fsid); i++)
+- (void)printf("%02x", ((u_char *)&sfp->f_fsid)[i]);
++ asprintf(&fsidbuf, "%s%02x", fsidbuf, ((u_char *)&sfp->f_fsid)[i]);
++ xo_emit("{:fsid}", fsidbuf);
++ free(fsidbuf);
+ }
+ }
+- (void)printf(")\n");
++ xo_emit("{D:)}\n");
+ }
+
+ struct statfs *
+@@ -703,7 +743,7 @@ catopt(char *s0, const char *s1)
+
+ if (s0 && *s0) {
+ if (asprintf(&cp, "%s,%s", s0, s1) == -1)
+- errx(1, "asprintf failed");
++ xo_errx(1, "asprintf failed");
+ } else
+ cp = strdup(s1);
+
+@@ -758,7 +798,7 @@ mangle(char *options, struct cpa *a)
+ }
+
+ if (mountprog == NULL) {
+- errx(1, "Need value for -o mountprog");
++ xo_errx(1, "Need value for -o mountprog");
+ }
+ continue;
+ } else if (strcmp(p, "userquota") == 0) {
+@@ -824,7 +864,7 @@ update_options(char *opts, char *fstab, int curflags)
+ newopt = NULL;
+ for (p = expopt; (o = strsep(&p, ",")) != NULL;) {
+ if ((tmpopt = malloc( strlen(o) + 2 + 1 )) == NULL)
+- errx(1, "malloc failed");
++ xo_errx(1, "malloc failed");
+
+ strcpy(tmpopt, "no");
+ strcat(tmpopt, o);
+@@ -867,11 +907,11 @@ void
+ usage(void)
+ {
+
+- (void)fprintf(stderr, "%s\n%s\n%s\n",
++ xo_error("%s\n%s\n%s\n",
+ "usage: mount [-adflpruvw] [-F fstab] [-o options] [-t ufs | external_type]",
+ " mount [-dfpruvw] special | node",
+ " mount [-dfpruvw] [-o options] [-t ufs | external_type] special node");
+- exit(1);
++ EXIT(1);
+ }
+
+ void
+@@ -899,32 +939,36 @@ putfsent(struct statfs *ent)
+ }
+
+ l = strlen(ent->f_mntfromname);
+- printf("%s%s%s%s", ent->f_mntfromname,
++ xo_emit("{:device}{P:/%s}{P:/%s}{P:/%s}",
++ ent->f_mntfromname,
+ l < 8 ? "\t" : "",
+ l < 16 ? "\t" : "",
+ l < 24 ? "\t" : " ");
+ l = strlen(ent->f_mntonname);
+- printf("%s%s%s%s", ent->f_mntonname,
++ xo_emit("{:mntpoint}{P:/%s}{P:/%s}{P:/%s}",
++ ent->f_mntonname,
+ l < 8 ? "\t" : "",
+ l < 16 ? "\t" : "",
+ l < 24 ? "\t" : " ");
+- printf("%s\t", ent->f_fstypename);
++ xo_emit("{:fstype}{P:\t}", ent->f_fstypename);
+ l = strlen(opts);
+- printf("%s%s", opts,
++ xo_emit("{:opts}{P:/%s}", opts,
+ l < 8 ? "\t" : " ");
+ free(opts);
+
+ if ((fst = getfsspec(ent->f_mntfromname)))
+- printf("\t%u %u\n", fst->fs_freq, fst->fs_passno);
++ xo_emit("{P:\t}{n:dump/%u}{P: }{n:pass/%u}\n",
++ fst->fs_freq, fst->fs_passno);
+ else if ((fst = getfsfile(ent->f_mntonname)))
+- printf("\t%u %u\n", fst->fs_freq, fst->fs_passno);
++ xo_emit("{P:\t}{n:dump/%u}{P: }{n:pass/%u}\n",
++ fst->fs_freq, fst->fs_passno);
+ else if (strcmp(ent->f_fstypename, "ufs") == 0) {
+ if (strcmp(ent->f_mntonname, "/") == 0)
+- printf("\t1 1\n");
++ xo_emit("{P:\t}{n:dump/1}{P: }{n:pass/1}\n");
+ else
+- printf("\t2 2\n");
++ xo_emit("{P:\t}{n:dump/2}{P: }{n:pass/2}\n");
+ } else
+- printf("\t0 0\n");
++ xo_emit("{P:\t}{n:dump/0}{P: }{n:pass/0}\n");
+ }
+
+
+--
+2.31.1
+