]> git.cameronkatri.com Git - freebsd-patches.git/commitdiff
Initial
authorCameron Katri <me@cameronkatri.com>
Sun, 30 May 2021 21:21:13 +0000 (17:21 -0400)
committerCameron Katri <me@cameronkatri.com>
Sun, 30 May 2021 21:21:13 +0000 (17:21 -0400)
README.md [new file with mode: 0644]
acpiconf-8-Add-libxo-3-support.patch [new file with mode: 0644]
diff-1-Add-color-support.patch [new file with mode: 0644]
ls-1-Allow-LSCOLORS-to-specify-an-underline.patch [new file with mode: 0644]
mount-8-Add-libxo-3-support.patch [new file with mode: 0644]

diff --git a/README.md b/README.md
new file mode 100644 (file)
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 (file)
index 0000000..641c18f
--- /dev/null
@@ -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 (file)
index 0000000..31b1fde
--- /dev/null
@@ -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 (file)
index 0000000..095d6f3
--- /dev/null
@@ -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 (file)
index 0000000..353a758
--- /dev/null
@@ -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
+