[PATCH netcat] Use correct preposition in verbose reports

2020-09-20 Thread Duncan Roe
Rather than reporting everything as "on" report e.g.
"Connection received from", "Bound to" and so on.

Signed-off-by: Duncan Roe 
---
 usr.bin/nc/netcat.c | 14 +++---
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/usr.bin/nc/netcat.c b/usr.bin/nc/netcat.c
index 503095584ad..528dbeea678 100644
--- a/usr.bin/nc/netcat.c
+++ b/usr.bin/nc/netcat.c
@@ -615,7 +615,7 @@ main(int argc, char *argv[])
err(1, "pledge");
}
if (vflag)
-   report_sock("Connection received",
+   report_sock("Connection received from",
(struct sockaddr *), len,
family == AF_UNIX ? host : NULL);
 
@@ -632,7 +632,7 @@ main(int argc, char *argv[])
err(1, "accept");
}
if (vflag)
-   report_sock("Connection received",
+   report_sock("Connection received from",
(struct sockaddr *), len,
family == AF_UNIX ? host : NULL);
if ((usetls) &&
@@ -786,7 +786,7 @@ unix_bind(char *path, int flags)
return -1;
}
if (vflag)
-   report_sock("Bound", NULL, 0, path);
+   report_sock("Bound to", NULL, 0, path);
 
return s;
 }
@@ -932,7 +932,7 @@ unix_listen(char *path)
return -1;
}
if (vflag)
-   report_sock("Listening", NULL, 0, path);
+   report_sock("Listening on", NULL, 0, path);
 
return s;
 }
@@ -1103,7 +1103,7 @@ local_listen(const char *host, const char *port, struct 
addrinfo hints)
len = sizeof(ss);
if (getsockname(s, (struct sockaddr *), ) == -1)
err(1, "getsockname");
-   report_sock(uflag ? "Bound" : "Listening",
+   report_sock(uflag ? "Bound to" : "Listening on",
(struct sockaddr *), len, NULL);
}
 
@@ -1770,7 +1770,7 @@ report_sock(const char *msg, const struct sockaddr *sa, 
socklen_t salen,
int flags = NI_NUMERICSERV;
 
if (path != NULL) {
-   fprintf(stderr, "%s on %s\n", msg, path);
+   fprintf(stderr, "%s %s\n", msg, path);
return;
}
 
@@ -1788,7 +1788,7 @@ report_sock(const char *msg, const struct sockaddr *sa, 
socklen_t salen,
errx(1, "getnameinfo: %s", gai_strerror(herr));
}
 
-   fprintf(stderr, "%s on %s %s\n", msg, host, port);
+   fprintf(stderr, "%s %s %s\n", msg, host, port);
 }
 
 void
-- 
2.24.2



[PATCH 3/3] route(8): fail on nonexistent interfaces

2020-09-20 Thread Demi M. Obenour
Previously, a nonexistent interface would be converted to the invalid
interface index 0.  This is now rejected by the kernel, but route(8) can
give a better error message by failing fast.
---
 sbin/route/route.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git sbin/route/route.c sbin/route/route.c
index f1ec5bd38d8..13ab171cfd4 100644
--- sbin/route/route.c
+++ sbin/route/route.c
@@ -899,7 +899,8 @@ getaddr(int which, int af, char *s, struct hostent **hpp)
}
 
case AF_LINK:
-   su->sdl.sdl_index = if_nametoindex(s);
+   if ((su->sdl.sdl_index = if_nametoindex(s)) == 0)
+   errx(1, "no such interface %s", s);
memset(>sdl.sdl_data, 0, sizeof(su->sdl.sdl_data));
return (1);
case AF_MPLS:
-- 
2.26.2



[PATCH 2/3] Check for user-specified interfaces in RTA_GATEWAY

2020-09-20 Thread Demi M. Obenour
Both RTA_IFP and RTA_GATEWAY can use a sockaddr_dl struct.  If either
specifies an explicit interface index, it must be honored.  If both do,
and they are not equal, that is an error.  It is also an error if RTA_IFP
specifies an index of 0.

Furthermore, if RTA_GATEWAY specifies a sockaddr_dl, it must not be used
where an AF_INET or AF_INET6 address is required.
---
 sys/net/rtsock.c | 27 +--
 1 file changed, 21 insertions(+), 6 deletions(-)

diff --git sys/net/rtsock.c sys/net/rtsock.c
index a156674fa6a..0ddab28272a 100644
--- sys/net/rtsock.c
+++ sys/net/rtsock.c
@@ -1221,6 +1221,7 @@ int
 rtm_getifa(struct rt_addrinfo *info, unsigned int rtid)
 {
struct ifnet*ifp = NULL;
+   uint16_tif_index = 0;
 
/*
 * The "returned" `ifa' is guaranteed to be alive only if
@@ -1229,16 +1230,29 @@ rtm_getifa(struct rt_addrinfo *info, unsigned int rtid)
NET_ASSERT_LOCKED();
 
/*
-* ifp may be specified by sockaddr_dl; if so, it must be honored.
+* ifp and/or gateway may be specified by sockaddr_dl; if so, it must be
+* honored.
 */
if (info->rti_info[RTAX_IFP] != NULL) {
-   struct sockaddr_dl *sdl;
+   if_index = satosdl(info->rti_info[RTAX_IFP])->sdl_index;
+   if (if_index == 0)
+   return (EINVAL);
+   }
+
+   if (info->rti_info[RTAX_GATEWAY] != NULL &&
+   info->rti_info[RTAX_GATEWAY]->sa_family == AF_LINK) {
+   uint16_t gateway_if;
 
-   sdl = satosdl(info->rti_info[RTAX_IFP]);
-   if ((ifp = if_get(sdl->sdl_index)) == NULL)
-   return (ENXIO);
+   gateway_if = satosdl(info->rti_info[RTAX_GATEWAY])->sdl_index;
+   if (if_index == 0)
+   if_index = gateway_if;
+   else if (gateway_if != if_index)
+   return (EINVAL);
}
 
+   if (if_index != 0 && (ifp = if_get(if_index)) == NULL)
+   return (ENXIO);
+
 #ifdef IPSEC
/*
 * If the destination is a PF_KEY address, we'll look
@@ -1269,7 +1283,8 @@ rtm_getifa(struct rt_addrinfo *info, unsigned int rtid)
struct sockaddr *sa;
 
if ((sa = info->rti_info[RTAX_IFA]) == NULL)
-   if ((sa = info->rti_info[RTAX_GATEWAY]) == NULL)
+   if ((sa = info->rti_info[RTAX_GATEWAY]) == NULL ||
+   sa->sa_family == AF_LINK)
sa = info->rti_info[RTAX_DST];
 
if (sa != NULL && ifp != NULL)
-- 
2.26.2




[PATCH 1/3] rtm_getifa: Never ignore RTA_IFP

2020-09-20 Thread Demi M. Obenour
If an RTM_ADD command on a routing socket includes an RTA_IFA sockaddr,
and that sockaddr is an exact match for one of the interfaces in the
relevant routing domain, any RTA_IFP sockaddr in the same message is
ignored.  If there are multiple interfaces with the same IP address,
this can cause packets to be sent out the wrong interface.  Fix this
by skipping the exact-match check on RTA_IFA if an RTA_IFP sockaddr
was sent.

The RTA_IFP sockaddr was also being ignored if there was no interface
with the requested index.  Return ENXIO to userspace instead.

The bug can easily be seen by running the following commands as root
on a machine where vether0 and vether1 do not exist, and on which
the subnet 192.0.2.0/24 (reserved for documentation) is not in use:

vether1 -ifp vether1 -inet -ifa "$dummy_ip"

On a system with an unpatched kernel, the final command will show
that the route to 192.0.2.6 is via vether0.  If this patch has been
applied, the route to 192.0.2.6 will be (correctly) via vether1.
---
 sys/net/rtsock.c   | 34 --
 usr.sbin/arp/arp.c |  4 +---
 2 files changed, 25 insertions(+), 13 deletions(-)

diff --git sys/net/rtsock.c sys/net/rtsock.c
index fa84ddc25e5..a156674fa6a 100644
--- sys/net/rtsock.c
+++ sys/net/rtsock.c
@@ -75,6 +75,7 @@
 
 #include 
 #include 
+#include 
 #include 
 #include 
 
@@ -1228,29 +1229,40 @@ rtm_getifa(struct rt_addrinfo *info, unsigned int rtid)
NET_ASSERT_LOCKED();
 
/*
-* ifp may be specified by sockaddr_dl when protocol address
-* is ambiguous
+* ifp may be specified by sockaddr_dl; if so, it must be honored.
 */
if (info->rti_info[RTAX_IFP] != NULL) {
struct sockaddr_dl *sdl;
 
sdl = satosdl(info->rti_info[RTAX_IFP]);
-   ifp = if_get(sdl->sdl_index);
+   if ((ifp = if_get(sdl->sdl_index)) == NULL)
+   return (ENXIO);
}
 
 #ifdef IPSEC
/*
 * If the destination is a PF_KEY address, we'll look
-* for the existence of a encap interface number or address
-* in the options list of the gateway. By default, we'll return
-* enc0.
+* for the existence of a encap interface number as the output
+* interface.
 */
if (info->rti_info[RTAX_DST] &&
-   info->rti_info[RTAX_DST]->sa_family == PF_KEY)
-   info->rti_ifa = enc_getifa(rtid, 0);
+   info->rti_info[RTAX_DST]->sa_family == PF_KEY) {
+   if (ifp != NULL) {
+   struct enc_softc *sc;
+   if (ifp->if_type != IFT_ENC) {
+   if_put(ifp);
+   return (EINVAL);
+   }
+   sc = ifp->if_softc;
+   info->rti_ifa = >sc_ifa;
+   } else
+   info->rti_ifa = enc_getifa(rtid, 0);
+   }
 #endif
 
-   if (info->rti_ifa == NULL && info->rti_info[RTAX_IFA] != NULL)
+   /* ifp overrides even an exact match on RTAX_IFA */
+   if (info->rti_ifa == NULL && ifp == NULL &&
+   info->rti_info[RTAX_IFA] != NULL)
info->rti_ifa = ifa_ifwithaddr(info->rti_info[RTAX_IFA], rtid);
 
if (info->rti_ifa == NULL) {
@@ -1273,6 +1285,9 @@ rtm_getifa(struct rt_addrinfo *info, unsigned int rtid)
sa, sa, rtid);
}
 
+   KASSERT(info->rti_ifa == NULL || ifp == NULL ||
+   ifp == info->rti_ifa->ifa_ifp);
+
if_put(ifp);
 
if (info->rti_ifa == NULL)
@@ -1435,7 +1450,6 @@ rtm_xaddrs(caddr_t cp, caddr_t cplim, struct rt_addrinfo 
*rtinfo)
/*
 * XXX Should be sizeof(struct sockaddr_dl), but
 * route(8) has a bug and provides less memory.
-* arp(8) has another bug and uses sizeof pointer.
 */
size = 4;
break;
diff --git usr.sbin/arp/arp.c usr.sbin/arp/arp.c
index b09eedd7ec9..09d5b5034b8 100644
--- usr.sbin/arp/arp.c
+++ usr.sbin/arp/arp.c
@@ -259,7 +259,6 @@ parse_host(const char *host, struct in_addr *in)
 struct sockaddr_in so_mask = { 8, 0, 0, { 0x } };
 struct sockaddr_inarp  blank_sin = { sizeof(blank_sin), AF_INET }, sin_m;
 struct sockaddr_dl blank_sdl = { sizeof(blank_sdl), AF_LINK }, sdl_m;
-struct sockaddr_dl ifp_m = { sizeof(ifp_m), AF_LINK };
 time_t expire_time;
 intflags, export_only, doing_proxy, found_entry;
 struct {
@@ -646,7 +645,7 @@ rtmsg(int cmd)
}
/* FALLTHROUGH */
case RTM_GET:
-   rtm->rtm_addrs |= (RTA_DST | RTA_IFP);
+   rtm->rtm_addrs |= RTA_DST;
}
 
 #define NEXTADDR(w, s) \
@@ -658,7 +657,6 @@ rtmsg(int cmd)

Re: httpd(8): don't leak iov

2020-09-20 Thread Jeremie Courreges-Anglas
On Sun, Sep 20 2020, Tobias Heider  wrote:
> iov is allocated with calloc.  I think we should free it after the imsg
> is sent.
>
> ok?

ok jca@

> Index: config.c
> ===
> RCS file: /cvs/src/usr.sbin/httpd/config.c,v
> retrieving revision 1.57
> diff -u -p -r1.57 config.c
> --- config.c  8 May 2019 19:57:45 -   1.57
> +++ config.c  20 Sep 2020 13:34:07 -
> @@ -387,8 +387,10 @@ config_setserver_fcgiparams(struct httpd
>   if (proc_composev(ps, PROC_SERVER, IMSG_CFG_FCGI, iov, c) != 0) {
>   log_warn("%s: failed to compose IMSG_CFG_FCGI imsg for "
>   "`%s'", __func__, srv_conf->name);
> + free(iov);
>   return (-1);
>   }
> + free(iov);
>  
>   return (0);
>  }
>

-- 
jca | PGP : 0x1524E7EE / 5135 92C1 AD36 5293 2BDF  DDCC 0DFA 74AE 1524 E7EE



Re: fix eeprom(8) on macppc

2020-09-20 Thread Miod Vallat
> > Suggested diff below; clue from NetBSD.
> I looked for openprom code there but only found it for SPARC, can you
> point me to where you got the "clue" from exactly?

http://bxr.su/NetBSD/sys/dev/ofw/openfirmio.c#205



Re: fix eeprom(8) on macppc

2020-09-20 Thread Klemens Nanni
On Sun, Sep 20, 2020 at 06:01:08PM +, Miod Vallat wrote:
> I had noticed for years that eeprom(8) always reported failure when
> attempting to change OpenFirmware environment variables on macppc.
> 
> Upon further examination, it doesn't - the variables get changed, but
> error is reported. This is caused by a difference in implementation
> behaviour between Apple's OpenFirmware and Sun's.
> 
> Suggested diff below; clue from NetBSD.
I looked for openprom code there but only found it for SPARC, can you
point me to where you got the "clue" from exactly?

> Before:
> # eeprom boot-command
> boot-command=mac-boot
> # eeprom boot-command=boot
> eeprom: invalid keyword: boot-command
> # eeprom boot-command
> boot-command=boot   <-- yet the value has been changed
> 
> After:
> # eeprom boot-command
> boot-command=mac-boot
> # eeprom boot-command=boot
> # eeprom boot-command
> boot-command=boot
Confirmed on my PowerBook G4.

OK kn



fix eeprom(8) on macppc

2020-09-20 Thread Miod Vallat
I had noticed for years that eeprom(8) always reported failure when
attempting to change OpenFirmware environment variables on macppc.

Upon further examination, it doesn't - the variables get changed, but
error is reported. This is caused by a difference in implementation
behaviour between Apple's OpenFirmware and Sun's.

Suggested diff below; clue from NetBSD.

Before:
# eeprom boot-command
boot-command=mac-boot
# eeprom boot-command=boot
eeprom: invalid keyword: boot-command
# eeprom boot-command
boot-command=boot   <-- yet the value has been changed

After:
# eeprom boot-command
boot-command=mac-boot
# eeprom boot-command=boot
# eeprom boot-command
boot-command=boot


Index: openprom.c
===
RCS file: /OpenBSD/src/sys/arch/macppc/macppc/openprom.c,v
retrieving revision 1.4
diff -u -p -r1.4 openprom.c
--- openprom.c  19 Sep 2015 21:07:04 -  1.4
+++ openprom.c  20 Sep 2020 17:56:35 -
@@ -186,7 +186,11 @@ openpromioctl(dev_t dev, u_long cmd, cad
strlcpy(buf, name, 32); /* XXX */
len = OF_setprop(node, buf, value, op->op_buflen + 1);
splx(s);
-   if (len != op->op_buflen)
+   /*
+* For string properties, the Apple OpenFirmware implementation
+* returns the buffer length including the trailing NUL.
+*/
+   if (len != op->op_buflen && len != op->op_buflen + 1)
error = EINVAL;
break;
 



Re: diff: pfctl: error message for nonexisting rtable

2020-09-20 Thread Klemens Nanni
On Tue, Sep 15, 2020 at 02:31:24AM +0200, Klemens Nanni wrote:
> On Tue, Sep 15, 2020 at 12:30:35AM +0200, Klemens Nanni wrote:
> > Actually, that should just work regardless of whether the rounting
> > domain exists at ruleset creation time;  just like it is the case with
> > interface names/groups which may come and go at runtime without
> > requiring changes to the ruleset.
> > 
> > Rules on nonexistent interfaces won't match, routing domains (and
> > ultimately routing tables) should behave the same, I think.
> > 
> > Here's a diff that does this for routing domains allowing me to always
> > use `on rdomain 5' - I've tested it with a few examplatory rulesets and
> > behaviour is as expected.
> > 
> > It will need more eye balling and I am not pushing such changes before
> > release, but if that is a general direction we agree, your proposed
> > `rtable' fix could move along and become just as flexible instead.
> More on this:
> 
>   # ifconfig lo1 rdomain 1
>   # echo pass on rdomain 1 | pfctl -f-
>   # ifconfig lo1 destroy
>   # pfctl -sr 
>  
>   pass on rdomain 1 all flags S/SA
> 
> The ruleset stays valid and continues to work as soon as routing domain
> `1' reappears, there is no reason to require existence of it at ruleset
> creation;  this is safe because routing domains are just normative
> numbers, there's no further state when it comes to filtering - either
> the id on the packet matches the number in the ruleset or it doesn't.
> 
> Routing tables however are more involved as they can be used to *alter*
> a packet's flow in pf.conf(5), so requiring them to be present at
> ruleset creation makes sense to guarantee that pf will only ever change
> routing table ids to valid ones.
> 
> Routing domains can be deleted, but that doesn't invalidate rules like
> `on rdomain 1', which simply won't match when the given id does not
> exist.
> 
> Routing tables however cannot be deleted, they get moved to the default
> routing domain whenever their corresponding routing domain disappears;
> this is in line with only ever loading valid routing table ids into pf.
> 
> So unless I missed something, that ruleset creation (`pfctl -f ...')
> is the only occasion pf actually needs to validate routing table ids:
> they are guaranteed to always exist from then on.
> 
> Given this, my diff looks fine as is and should not change `rtable'
> behaviour - YASUOKA's diff is also fine as is and actually implements
> the validity check I just mentioned, obsoleting my initial feedback.

Rebased diff after yasouka's pfctl commit;  it still takes care of
rdomains only, but I'd appreciate folks using `on rdomain' in their
pf.conf test this.  If this works out I'd like to put it in shortly
after release and work on rtables next.


Index: sys/net/pf_ioctl.c
===
RCS file: /cvs/src/sys/net/pf_ioctl.c,v
retrieving revision 1.356
diff -u -p -r1.356 pf_ioctl.c
--- sys/net/pf_ioctl.c  24 Aug 2020 15:41:15 -  1.356
+++ sys/net/pf_ioctl.c  14 Sep 2020 22:27:55 -
@@ -2820,10 +2820,8 @@ pf_rule_copyin(struct pf_rule *from, str
if (to->rtableid >= 0 && !rtable_exists(to->rtableid))
return (EBUSY);
to->onrdomain = from->onrdomain;
-   if (to->onrdomain >= 0 && !rtable_exists(to->onrdomain))
-   return (EBUSY);
-   if (to->onrdomain >= 0) /* make sure it is a real rdomain */
-   to->onrdomain = rtable_l2(to->onrdomain);
+   if (to->rtableid < 0 || to->rtableid > RT_TABLEID_MAX)
+   return (EINVAL);
 
for (i = 0; i < PFTM_MAX; i++)
to->timeout[i] = from->timeout[i];
Index: sbin/pfctl/parse.y
===
RCS file: /cvs/src/sbin/pfctl/parse.y,v
retrieving revision 1.703
diff -u -p -r1.703 parse.y
--- sbin/pfctl/parse.y  17 Sep 2020 14:26:59 -  1.703
+++ sbin/pfctl/parse.y  20 Sep 2020 17:28:10 -
@@ -1216,7 +1216,7 @@ antispoof_opt : LABEL label   {
if ($2 < 0 || $2 > RT_TABLEID_MAX) {
yyerror("invalid rtable id");
YYERROR;
-   } else if (lookup_rtable($2) < 1) {
+   } else if (!lookup_rtable($2)) {
yyerror("rtable %lld does not exist", $2);
YYERROR;
}
@@ -2003,7 +2003,7 @@ filter_opt: USER uids {
if ($2 < 0 || $2 > RT_TABLEID_MAX) {
yyerror("invalid rtable id");
YYERROR;
-   } else if (lookup_rtable($2) < 1) {
+   } else if (!lookup_rtable($2)) {
yyerror("rtable %lld does not exist", $2);
YYERROR;
 

Re: ksh "clear-screen" for vi mode

2020-09-20 Thread Uwe Werler
On 20 Sep 06:14, Todd C. Miller wrote:
> On Sun, 20 Sep 2020 05:39:02 +0200, Theo Buehler wrote:
> 
> > This works and appears to match bash's behavior in that it only works
> > in normal mode. I would slightly prefer to also add the command to the
> > nonstandard vi commands in the switch around line 650 to have it
> > available from insert mode as well. This would match zsh's behavior.
> 
> Sure, I was comparing it to bash so didn't support insert mode.
> I agree that it's more useful to have it available there too.
> 
>  - todd
> 
> Index: bin/ksh/ksh.1
> ===
> RCS file: /cvs/src/bin/ksh/ksh.1,v
> retrieving revision 1.209
> diff -u -p -u -r1.209 ksh.1
> --- bin/ksh/ksh.1 7 Jul 2020 10:33:58 -   1.209
> +++ bin/ksh/ksh.1 20 Sep 2020 12:12:01 -
> @@ -5053,6 +5053,12 @@ Erases previous character.
>  .It ^J | ^M
>  End of line.
>  The current line is read, parsed, and executed by the shell.
> +.It ^L
> +Clear screen.
> +The screen is cleared if the
> +.Ev TERM
> +parameter is set and the terminal supports clearing the screen.
> +The prompt string and the current line are redrawn.
>  .It ^V
>  Literal next.
>  The next character typed is not treated specially (can be used
> Index: bin/ksh/vi.c
> ===
> RCS file: /cvs/src/bin/ksh/vi.c,v
> retrieving revision 1.56
> diff -u -p -u -r1.56 vi.c
> --- bin/ksh/vi.c  15 Mar 2018 16:51:29 -  1.56
> +++ bin/ksh/vi.c  20 Sep 2020 12:02:38 -
> @@ -14,12 +14,14 @@
>  #include 
>  #include 
>  #include 
> +#ifndef SMALL
> +# include 
> +# include 
> +#endif
>  
>  #include "sh.h"
>  #include "edit.h"
>  
> -#define CTRL(c)  (c & 0x1f)
> -
>  struct edstate {
>   char*cbuf;  /* main buffer to build the command line */
>   int cbufsize;   /* number of bytes allocated for cbuf */
> @@ -52,8 +54,9 @@ static int  Backword(int);
>  static int   Endword(int);
>  static int   grabhist(int, int);
>  static int   grabsearch(int, int, int, char *);
> +static void  do_clear_screen(void);
>  static void  redraw_line(int);
> -static void  refresh(int);
> +static void  refresh_line(int);
>  static int   outofwin(void);
>  static void  rewindow(void);
>  static int   newcol(int, int);
> @@ -271,9 +274,9 @@ vi_hook(int ch)
>   case 0:
>   if (state == VLIT) {
>   es->cursor--;
> - refresh(0);
> + refresh_line(0);
>   } else
> - refresh(insert != 0);
> + refresh_line(insert != 0);
>   break;
>   case 1:
>   return 1;
> @@ -298,7 +301,7 @@ vi_hook(int ch)
>   return -1;
>   } else if (putbuf("?", 1, 0) != 0)
>   return -1;
> - refresh(0);
> + refresh_line(0);
>   }
>   }
>   }
> @@ -310,7 +313,7 @@ vi_hook(int ch)
>   vi_error();
>   } else
>   es->cbuf[es->cursor++] = ch;
> - refresh(1);
> + refresh_line(1);
>   state = VNORMAL;
>   break;
>  
> @@ -375,7 +378,7 @@ vi_hook(int ch)
>   if (!srchpat[0]) {
>   vi_error();
>   state = VNORMAL;
> - refresh(0);
> + refresh_line(0);
>   return 0;
>   }
>   } else {
> @@ -392,17 +395,17 @@ vi_hook(int ch)
>   } while (srchlen > 0 &&
>   isu8cont(locpat[srchlen]));
>   es->cursor = es->linelen;
> - refresh(0);
> + refresh_line(0);
>   return 0;
>   }
>   restore_cbuf();
>   state = VNORMAL;
> - refresh(0);
> + refresh_line(0);
>   } else if (ch == edchars.kill) {
>   srchlen = 0;
>   es->linelen = 1;
>   es->cursor = 1;
> - refresh(0);
> + refresh_line(0);
>   return 0;
>   } else if (ch == edchars.werase) {
>   struct edstate new_es, *save_es;
> @@ -421,7 +424,7 @@ vi_hook(int ch)

snmp(1) Add support for printing human readable enums

2020-09-20 Thread Martijn van Duren
SNMP contains quite a few enumerations, which are annoying to read, even
if you have the MIB at hand. This diff adds support for integer
enumerations. I've only implemented TruthValue for now, but others
should be easy to add. I went for a normal linear search since most
enums don't even hit 10 elements, comparison is int-based and thus the
added complexity of something like RB_* seems like enormous overkill.

I've removed BER_TYPE_BOOLEAN, since it's not part of the SNMP-spec and
thus dead code. I added it originally because snmpd's smi.c contained
it.

I should probably rewrite smi_print_element at some point, but I'm not
confident enough in its intricacies to make that jump just yet. One
thing at a time.

OK?

martijn@

Index: mib.h
===
RCS file: /cvs/src/usr.bin/snmp/mib.h,v
retrieving revision 1.8
diff -u -p -r1.8 mib.h
--- mib.h   12 Sep 2020 18:11:43 -  1.8
+++ mib.h   20 Sep 2020 15:23:48 -
@@ -1034,8 +1034,8 @@
{ MIBDECL(ifHCOutBroadcastPkts) },  \
{ MIBDECL(ifLinkUpDownTrapEnable) },\
{ MIBDECL(ifHighSpeed) },   \
-   { MIBDECL(ifPromiscuousMode) }, \
-   { MIBDECL(ifConnectorPresent) },\
+   { MIBDECL(ifPromiscuousMode), "TruthValue" },   \
+   { MIBDECL(ifConnectorPresent), "TruthValue" },  \
{ MIBDECL(ifAlias) },   \
{ MIBDECL(ifCounterDiscontinuityTime) },\
{ MIBDECL(ifStackTable) },  \
@@ -1460,10 +1460,15 @@
{ MIBEND }  \
 }
 
-#define TEXTCONV_TREE {\
-   { "SnmpAdminString", "255t", BER_TYPE_OCTETSTRING }, \
-   { "DisplayString", "255a", BER_TYPE_OCTETSTRING }, \
-   { NULL, NULL }  \
+#define TEXTCONV_TREE {
\
+   { "SnmpAdminString", BER_TYPE_OCTETSTRING, "255t" },\
+   { "DisplayString", BER_TYPE_OCTETSTRING, "255a" },  \
+   { "TruthValue", BER_TYPE_INTEGER, NULL, (struct textconv_enum[]){\
+   { 1, "true" },  \
+   { 2, "false" }, \
+   {}  \
+   }}, \
+   {  }\
 }
 
 voidmib_init(void);
Index: smi.c
===
RCS file: /cvs/src/usr.bin/snmp/smi.c,v
retrieving revision 1.12
diff -u -p -r1.12 smi.c
--- smi.c   8 Aug 2020 13:02:54 -   1.12
+++ smi.c   20 Sep 2020 15:23:48 -
@@ -39,6 +39,7 @@
 #define MINIMUM(a, b)  (((a) < (b)) ? (a) : (b))
 
 char *smi_displayhint_os(struct textconv *, int, const char *, size_t, int);
+char *smi_displayhint_int(struct textconv*, int, long long);
 
 int smi_oid_cmp(struct oid *, struct oid *);
 int smi_key_cmp(struct oid *, struct oid *);
@@ -254,7 +255,6 @@ smi_print_element(struct ber_oid *oid, s
struct textconv  tckey;
size_t   len, i, slen;
long longv, ticks;
-   int  d;
int  is_hex = 0, ret;
struct ber_oid   o;
char strbuf[BUFSIZ];
@@ -276,17 +276,6 @@ smi_print_element(struct ber_oid *oid, s
}
 
switch (root->be_encoding) {
-   case BER_TYPE_BOOLEAN:
-   if (ober_get_boolean(root, ) == -1)
-   goto fail;
-   if (print_hint) {
-   if (asprintf(, "INTEGER: %s(%d)",
-   d ? "true" : "false", d) == -1)
-   goto fail;
-   } else
-   if (asprintf(, "%s", d ? "true" : "false") == -1)
-   goto fail;
-   break;
case BER_TYPE_INTEGER:
case BER_TYPE_ENUMERATED:
if (ober_get_integer(root, ) == -1)
@@ -345,6 +334,10 @@ smi_print_element(struct ber_oid *oid, s
break;
}
hint = "INTEGER: ";
+   if (object != NULL && object->o_textconv != NULL &&
+   object->o_textconv->tc_syntax == root->be_encoding)
+   return smi_displayhint_int(object->o_textconv,
+   print_hint, v);
if (root->be_class == BER_CLASS_APPLICATION) {
if (root->be_type == SNMP_T_COUNTER32)
hint = "Counter32: ";
@@ -628,6 +621,31 @@ smi_foreach(struct oid *oid)
if (oid == NULL)
return RB_MIN(oidtree, _oidtree);
return RB_NEXT(oidtree, _oidtree, oid);
+}
+
+char *

Re: ksh "clear-screen" for vi mode

2020-09-20 Thread Uwe Werler
On 20 Sep 05:39, Theo Buehler wrote:
> On Sat, Sep 19, 2020 at 03:50:52PM -0600, Todd C. Miller wrote:
> > The vi and emacs edit code are completely separate.  Try the following
> > diff.  I had to rename a few things to avoid clashing with ncurses.h.
> 
> This works and appears to match bash's behavior in that it only works
> in normal mode. I would slightly prefer to also add the command to the
> nonstandard vi commands in the switch around line 650 to have it
> available from insert mode as well. This would match zsh's behavior.

That would be really great.

> 
> Either way, ok tb
> 



Re: ksh "clear-screen" for vi mode

2020-09-20 Thread Jason McIntyre
On Sun, Sep 20, 2020 at 08:19:24AM -0600, Todd C. Miller wrote:
> Does this look better?  I don't think we need to refer to the emacs
> clear-screen command in both cases; once should be sufficient.
> 
>  - todd
> 

i think it reads fine.
jmc

> Index: bin/ksh/ksh.1
> ===
> RCS file: /cvs/src/bin/ksh/ksh.1,v
> retrieving revision 1.209
> diff -u -p -u -r1.209 ksh.1
> --- bin/ksh/ksh.1 7 Jul 2020 10:33:58 -   1.209
> +++ bin/ksh/ksh.1 20 Sep 2020 14:16:50 -
> @@ -5053,6 +5053,13 @@ Erases previous character.
>  .It ^J | ^M
>  End of line.
>  The current line is read, parsed, and executed by the shell.
> +.It ^L
> +Clear the screen (if possible) and redraw the current line.
> +See the
> +.Em clear-screen
> +command in
> +.Sx Emacs editing mode
> +for more information.
>  .It ^V
>  Literal next.
>  The next character typed is not treated specially (can be used
> @@ -5510,7 +5517,9 @@ Miscellaneous vi commands
>  .Bl -tag -width Ds
>  .It ^J and ^M
>  The current line is read, parsed, and executed by the shell.
> -.It ^L and ^R
> +.It ^L
> +Clear the screen (if possible) and redraw the current line.
> +.It ^R
>  Redraw the current line.
>  .It Xo
>  .Oo Ar n Oc Ns \&.
> Index: bin/ksh/vi.c
> ===
> RCS file: /cvs/src/bin/ksh/vi.c,v
> retrieving revision 1.56
> diff -u -p -u -r1.56 vi.c
> --- bin/ksh/vi.c  15 Mar 2018 16:51:29 -  1.56
> +++ bin/ksh/vi.c  20 Sep 2020 12:02:38 -
> @@ -14,12 +14,14 @@
>  #include 
>  #include 
>  #include 
> +#ifndef SMALL
> +# include 
> +# include 
> +#endif
>  
>  #include "sh.h"
>  #include "edit.h"
>  
> -#define CTRL(c)  (c & 0x1f)
> -
>  struct edstate {
>   char*cbuf;  /* main buffer to build the command line */
>   int cbufsize;   /* number of bytes allocated for cbuf */
> @@ -52,8 +54,9 @@ static int  Backword(int);
>  static int   Endword(int);
>  static int   grabhist(int, int);
>  static int   grabsearch(int, int, int, char *);
> +static void  do_clear_screen(void);
>  static void  redraw_line(int);
> -static void  refresh(int);
> +static void  refresh_line(int);
>  static int   outofwin(void);
>  static void  rewindow(void);
>  static int   newcol(int, int);
> @@ -271,9 +274,9 @@ vi_hook(int ch)
>   case 0:
>   if (state == VLIT) {
>   es->cursor--;
> - refresh(0);
> + refresh_line(0);
>   } else
> - refresh(insert != 0);
> + refresh_line(insert != 0);
>   break;
>   case 1:
>   return 1;
> @@ -298,7 +301,7 @@ vi_hook(int ch)
>   return -1;
>   } else if (putbuf("?", 1, 0) != 0)
>   return -1;
> - refresh(0);
> + refresh_line(0);
>   }
>   }
>   }
> @@ -310,7 +313,7 @@ vi_hook(int ch)
>   vi_error();
>   } else
>   es->cbuf[es->cursor++] = ch;
> - refresh(1);
> + refresh_line(1);
>   state = VNORMAL;
>   break;
>  
> @@ -375,7 +378,7 @@ vi_hook(int ch)
>   if (!srchpat[0]) {
>   vi_error();
>   state = VNORMAL;
> - refresh(0);
> + refresh_line(0);
>   return 0;
>   }
>   } else {
> @@ -392,17 +395,17 @@ vi_hook(int ch)
>   } while (srchlen > 0 &&
>   isu8cont(locpat[srchlen]));
>   es->cursor = es->linelen;
> - refresh(0);
> + refresh_line(0);
>   return 0;
>   }
>   restore_cbuf();
>   state = VNORMAL;
> - refresh(0);
> + refresh_line(0);
>   } else if (ch == edchars.kill) {
>   srchlen = 0;
>   es->linelen = 1;
>   es->cursor = 1;
> - refresh(0);
> + refresh_line(0);
>   return 0;
>   } else if (ch == edchars.werase) {
>   struct edstate new_es, *save_es;
> @@ -421,7 +424,7 @@ vi_hook(int ch)
>   

Re: ksh "clear-screen" for vi mode

2020-09-20 Thread Todd C . Miller
Does this look better?  I don't think we need to refer to the emacs
clear-screen command in both cases; once should be sufficient.

 - todd

Index: bin/ksh/ksh.1
===
RCS file: /cvs/src/bin/ksh/ksh.1,v
retrieving revision 1.209
diff -u -p -u -r1.209 ksh.1
--- bin/ksh/ksh.1   7 Jul 2020 10:33:58 -   1.209
+++ bin/ksh/ksh.1   20 Sep 2020 14:16:50 -
@@ -5053,6 +5053,13 @@ Erases previous character.
 .It ^J | ^M
 End of line.
 The current line is read, parsed, and executed by the shell.
+.It ^L
+Clear the screen (if possible) and redraw the current line.
+See the
+.Em clear-screen
+command in
+.Sx Emacs editing mode
+for more information.
 .It ^V
 Literal next.
 The next character typed is not treated specially (can be used
@@ -5510,7 +5517,9 @@ Miscellaneous vi commands
 .Bl -tag -width Ds
 .It ^J and ^M
 The current line is read, parsed, and executed by the shell.
-.It ^L and ^R
+.It ^L
+Clear the screen (if possible) and redraw the current line.
+.It ^R
 Redraw the current line.
 .It Xo
 .Oo Ar n Oc Ns \&.
Index: bin/ksh/vi.c
===
RCS file: /cvs/src/bin/ksh/vi.c,v
retrieving revision 1.56
diff -u -p -u -r1.56 vi.c
--- bin/ksh/vi.c15 Mar 2018 16:51:29 -  1.56
+++ bin/ksh/vi.c20 Sep 2020 12:02:38 -
@@ -14,12 +14,14 @@
 #include 
 #include 
 #include 
+#ifndef SMALL
+# include 
+# include 
+#endif
 
 #include "sh.h"
 #include "edit.h"
 
-#define CTRL(c)(c & 0x1f)
-
 struct edstate {
char*cbuf;  /* main buffer to build the command line */
int cbufsize;   /* number of bytes allocated for cbuf */
@@ -52,8 +54,9 @@ static intBackword(int);
 static int Endword(int);
 static int grabhist(int, int);
 static int grabsearch(int, int, int, char *);
+static voiddo_clear_screen(void);
 static voidredraw_line(int);
-static voidrefresh(int);
+static voidrefresh_line(int);
 static int outofwin(void);
 static voidrewindow(void);
 static int newcol(int, int);
@@ -271,9 +274,9 @@ vi_hook(int ch)
case 0:
if (state == VLIT) {
es->cursor--;
-   refresh(0);
+   refresh_line(0);
} else
-   refresh(insert != 0);
+   refresh_line(insert != 0);
break;
case 1:
return 1;
@@ -298,7 +301,7 @@ vi_hook(int ch)
return -1;
} else if (putbuf("?", 1, 0) != 0)
return -1;
-   refresh(0);
+   refresh_line(0);
}
}
}
@@ -310,7 +313,7 @@ vi_hook(int ch)
vi_error();
} else
es->cbuf[es->cursor++] = ch;
-   refresh(1);
+   refresh_line(1);
state = VNORMAL;
break;
 
@@ -375,7 +378,7 @@ vi_hook(int ch)
if (!srchpat[0]) {
vi_error();
state = VNORMAL;
-   refresh(0);
+   refresh_line(0);
return 0;
}
} else {
@@ -392,17 +395,17 @@ vi_hook(int ch)
} while (srchlen > 0 &&
isu8cont(locpat[srchlen]));
es->cursor = es->linelen;
-   refresh(0);
+   refresh_line(0);
return 0;
}
restore_cbuf();
state = VNORMAL;
-   refresh(0);
+   refresh_line(0);
} else if (ch == edchars.kill) {
srchlen = 0;
es->linelen = 1;
es->cursor = 1;
-   refresh(0);
+   refresh_line(0);
return 0;
} else if (ch == edchars.werase) {
struct edstate new_es, *save_es;
@@ -421,7 +424,7 @@ vi_hook(int ch)
es->linelen -= char_len((unsigned 
char)locpat[i]);
srchlen = n;
es->cursor = es->linelen;
-   refresh(0);
+   

httpd(8): don't leak iov

2020-09-20 Thread Tobias Heider
iov is allocated with calloc.  I think we should free it after the imsg
is sent.

ok?

Index: config.c
===
RCS file: /cvs/src/usr.sbin/httpd/config.c,v
retrieving revision 1.57
diff -u -p -r1.57 config.c
--- config.c8 May 2019 19:57:45 -   1.57
+++ config.c20 Sep 2020 13:34:07 -
@@ -387,8 +387,10 @@ config_setserver_fcgiparams(struct httpd
if (proc_composev(ps, PROC_SERVER, IMSG_CFG_FCGI, iov, c) != 0) {
log_warn("%s: failed to compose IMSG_CFG_FCGI imsg for "
"`%s'", __func__, srv_conf->name);
+   free(iov);
return (-1);
}
+   free(iov);
 
return (0);
 }



apm(8) and apmd(8): zap "cool" running mode remnants

2020-09-20 Thread Jeremie Courreges-Anglas


apmd "cool" mode was removed in 2014, and -C was made an undocumented
compat alias for -A ("auto").

The code still contains kinda misleading references to this "cool"
running mode, the diff below zaps those.  ok?


Index: apm/apm.c
===
RCS file: /d/cvs/src/usr.sbin/apm/apm.c,v
retrieving revision 1.36
diff -u -p -r1.36 apm.c
--- apm/apm.c   28 Jun 2019 13:32:46 -  1.36
+++ apm/apm.c   20 Sep 2020 12:24:43 -
@@ -185,14 +185,10 @@ main(int argc, char *argv[])
action = HIBERNATE;
break;
case 'A':
-   if (action != NONE)
-   usage();
-   action = SETPERF_AUTO;
-   break;
case 'C':
if (action != NONE)
usage();
-   action = SETPERF_COOL;
+   action = SETPERF_AUTO;
break;
case 'H':
if (action != NONE)
@@ -277,7 +273,6 @@ main(int argc, char *argv[])
case SETPERF_LOW:
case SETPERF_HIGH:
case SETPERF_AUTO:
-   case SETPERF_COOL:
if (fd == -1)
errx(1, "cannot connect to apmd, "
"not changing performance adjustment mode");
Index: apmd/apm-proto.h
===
RCS file: /d/cvs/src/usr.sbin/apmd/apm-proto.h,v
retrieving revision 1.9
diff -u -p -r1.9 apm-proto.h
--- apmd/apm-proto.h26 Mar 2012 20:17:45 -  1.9
+++ apmd/apm-proto.h20 Sep 2020 12:28:01 -
@@ -38,7 +38,6 @@ enum apm_action {
SETPERF_LOW,
SETPERF_HIGH,
SETPERF_AUTO,
-   SETPERF_COOL
 };
 
 enum apm_state {
@@ -52,7 +51,6 @@ enum apm_perfmode {
PERF_NONE = -1,
PERF_MANUAL,
PERF_AUTO,
-   PERF_COOL
 };
 
 struct apm_command {
Index: apmd/apmd.c
===
RCS file: /d/cvs/src/usr.sbin/apmd/apmd.c,v
retrieving revision 1.96
diff -u -p -r1.96 apmd.c
--- apmd/apmd.c 13 Mar 2020 09:08:58 -  1.96
+++ apmd/apmd.c 20 Sep 2020 12:25:53 -
@@ -302,7 +302,6 @@ handle_client(int sock_fd, int ctl_fd)
setperfpolicy("high");
break;
case SETPERF_AUTO:
-   case SETPERF_COOL:
doperf = PERF_AUTO;
reply.newstate = NORMAL;
logmsg(LOG_NOTICE, "setting hw.perfpolicy to auto");
Index: apmd/apmsubr.c
===
RCS file: /d/cvs/src/usr.sbin/apmd/apmsubr.c,v
retrieving revision 1.8
diff -u -p -r1.8 apmsubr.c
--- apmd/apmsubr.c  15 Mar 2006 20:30:28 -  1.8
+++ apmd/apmsubr.c  20 Sep 2020 12:28:49 -
@@ -79,8 +79,6 @@ perf_mode(int mode)
return "manual";
case PERF_AUTO:
return "auto";
-   case PERF_COOL:
-   return "cool running";
default:
return "invalid";
}




-- 
jca | PGP : 0x1524E7EE / 5135 92C1 AD36 5293 2BDF  DDCC 0DFA 74AE 1524 E7EE



Re: ksh "clear-screen" for vi mode

2020-09-20 Thread Klemens Nanni
On Sun, Sep 20, 2020 at 06:14:22AM -0600, Todd C. Miller wrote:
> On Sun, 20 Sep 2020 05:39:02 +0200, Theo Buehler wrote:
> 
> > This works and appears to match bash's behavior in that it only works
> > in normal mode. I would slightly prefer to also add the command to the
> > nonstandard vi commands in the switch around line 650 to have it
> > available from insert mode as well. This would match zsh's behavior.
> 
> Sure, I was comparing it to bash so didn't support insert mode.
> I agree that it's more useful to have it available there too.
Works as expected, I cannot spot any regression either.

OK kn, but the could need further tweaks.

> Index: bin/ksh/ksh.1
> ===
> RCS file: /cvs/src/bin/ksh/ksh.1,v
> retrieving revision 1.209
> diff -u -p -u -r1.209 ksh.1
> --- bin/ksh/ksh.1 7 Jul 2020 10:33:58 -   1.209
> +++ bin/ksh/ksh.1 20 Sep 2020 12:12:01 -
> @@ -5053,6 +5053,12 @@ Erases previous character.
>  .It ^J | ^M
>  End of line.
>  The current line is read, parsed, and executed by the shell.
> +.It ^L
> +Clear screen.
> +The screen is cleared if the
> +.Ev TERM
> +parameter is set and the terminal supports clearing the screen.
> +The prompt string and the current line are redrawn.
This duplicates the `clear-screen' documentation in the
"Emacs editing mode" paragraph, perhaps just refer to that?

Otherwise it seems harder than necessary to grep for the same
functionality in two places.

Also, at the end of "Vi editing mode" there's another mention of `^L'
which needs updating now.

>  .It ^V
>  Literal next.
>  The next character typed is not treated specially (can be used



Re: ksh "clear-screen" for vi mode

2020-09-20 Thread Todd C . Miller
On Sun, 20 Sep 2020 05:39:02 +0200, Theo Buehler wrote:

> This works and appears to match bash's behavior in that it only works
> in normal mode. I would slightly prefer to also add the command to the
> nonstandard vi commands in the switch around line 650 to have it
> available from insert mode as well. This would match zsh's behavior.

Sure, I was comparing it to bash so didn't support insert mode.
I agree that it's more useful to have it available there too.

 - todd

Index: bin/ksh/ksh.1
===
RCS file: /cvs/src/bin/ksh/ksh.1,v
retrieving revision 1.209
diff -u -p -u -r1.209 ksh.1
--- bin/ksh/ksh.1   7 Jul 2020 10:33:58 -   1.209
+++ bin/ksh/ksh.1   20 Sep 2020 12:12:01 -
@@ -5053,6 +5053,12 @@ Erases previous character.
 .It ^J | ^M
 End of line.
 The current line is read, parsed, and executed by the shell.
+.It ^L
+Clear screen.
+The screen is cleared if the
+.Ev TERM
+parameter is set and the terminal supports clearing the screen.
+The prompt string and the current line are redrawn.
 .It ^V
 Literal next.
 The next character typed is not treated specially (can be used
Index: bin/ksh/vi.c
===
RCS file: /cvs/src/bin/ksh/vi.c,v
retrieving revision 1.56
diff -u -p -u -r1.56 vi.c
--- bin/ksh/vi.c15 Mar 2018 16:51:29 -  1.56
+++ bin/ksh/vi.c20 Sep 2020 12:02:38 -
@@ -14,12 +14,14 @@
 #include 
 #include 
 #include 
+#ifndef SMALL
+# include 
+# include 
+#endif
 
 #include "sh.h"
 #include "edit.h"
 
-#define CTRL(c)(c & 0x1f)
-
 struct edstate {
char*cbuf;  /* main buffer to build the command line */
int cbufsize;   /* number of bytes allocated for cbuf */
@@ -52,8 +54,9 @@ static intBackword(int);
 static int Endword(int);
 static int grabhist(int, int);
 static int grabsearch(int, int, int, char *);
+static voiddo_clear_screen(void);
 static voidredraw_line(int);
-static voidrefresh(int);
+static voidrefresh_line(int);
 static int outofwin(void);
 static voidrewindow(void);
 static int newcol(int, int);
@@ -271,9 +274,9 @@ vi_hook(int ch)
case 0:
if (state == VLIT) {
es->cursor--;
-   refresh(0);
+   refresh_line(0);
} else
-   refresh(insert != 0);
+   refresh_line(insert != 0);
break;
case 1:
return 1;
@@ -298,7 +301,7 @@ vi_hook(int ch)
return -1;
} else if (putbuf("?", 1, 0) != 0)
return -1;
-   refresh(0);
+   refresh_line(0);
}
}
}
@@ -310,7 +313,7 @@ vi_hook(int ch)
vi_error();
} else
es->cbuf[es->cursor++] = ch;
-   refresh(1);
+   refresh_line(1);
state = VNORMAL;
break;
 
@@ -375,7 +378,7 @@ vi_hook(int ch)
if (!srchpat[0]) {
vi_error();
state = VNORMAL;
-   refresh(0);
+   refresh_line(0);
return 0;
}
} else {
@@ -392,17 +395,17 @@ vi_hook(int ch)
} while (srchlen > 0 &&
isu8cont(locpat[srchlen]));
es->cursor = es->linelen;
-   refresh(0);
+   refresh_line(0);
return 0;
}
restore_cbuf();
state = VNORMAL;
-   refresh(0);
+   refresh_line(0);
} else if (ch == edchars.kill) {
srchlen = 0;
es->linelen = 1;
es->cursor = 1;
-   refresh(0);
+   refresh_line(0);
return 0;
} else if (ch == edchars.werase) {
struct edstate new_es, *save_es;
@@ -421,7 +424,7 @@ vi_hook(int ch)
es->linelen -= char_len((unsigned 
char)locpat[i]);
srchlen = n;

Re: ksh "clear-screen" for vi mode

2020-09-20 Thread Klemens Nanni
On Sun, Sep 20, 2020 at 05:39:02AM +0200, Theo Buehler wrote:
> On Sat, Sep 19, 2020 at 03:50:52PM -0600, Todd C. Miller wrote:
> > The vi and emacs edit code are completely separate.  Try the following
> > diff.  I had to rename a few things to avoid clashing with ncurses.h.
> 
> This works and appears to match bash's behavior in that it only works
> in normal mode. I would slightly prefer to also add the command to the
> nonstandard vi commands in the switch around line 650 to have it
> available from insert mode as well. This would match zsh's behavior.
Exactly.

> Either way, ok tb
OK kn for this diff just works and everything else is extra.