Enable cu(1) -l to accept the usb paths shown in hw.ucomnames.
authorkrw <krw@openbsd.org>
Mon, 2 Oct 2023 14:48:10 +0000 (14:48 +0000)
committerkrw <krw@openbsd.org>
Mon, 2 Oct 2023 14:48:10 +0000 (14:48 +0000)
Usual man page tweaks from jmc@ and schwarze@.

Testing various iterations by deraadt@, nicm@, kettenis@, drahn@.

ok deraadt@

usr.bin/cu/cu.1
usr.bin/cu/cu.c

index f9217c1..c4829cb 100644 (file)
@@ -1,4 +1,4 @@
-.\"    $OpenBSD: cu.1,v 1.22 2022/08/04 04:01:48 jsg Exp $
+.\"    $OpenBSD: cu.1,v 1.23 2023/10/02 14:48:10 krw Exp $
 .\"
 .\" Copyright (c) 1980, 1990, 1993
 .\"    The Regents of the University of California.  All rights reserved.
@@ -27,7 +27,7 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.Dd $Mdocdate: August 4 2022 $
+.Dd $Mdocdate: October 2 2023 $
 .Dt CU 1
 .Os
 .Sh NAME
@@ -60,11 +60,13 @@ should not allow the driver to block waiting for a carrier to be detected.
 Specify an escape character to use instead of the default tilde.
 .It Fl l Ar line
 Specify the line to use.
-Either of the forms like
-.Pa cua00
+Any of the forms
+.Pa cua00 ,
+.Pa /dev/cua00 ,
 or
-.Pa /dev/cua00
+.Pa usb0.1.2
 are permitted.
+.Pp
 The default is
 .Pa /dev/cua00 .
 See
@@ -75,6 +77,12 @@ Users in group
 are permitted to use
 .Xr cua 4
 devices by default.
+.Pp
+See
+.Xr sysctl 2
+.Va hw.ucomnames
+for available USB serial lines.
+.Pp
 .It Fl r
 Start
 .Nm
@@ -199,6 +207,8 @@ host description file
 .Sh EXIT STATUS
 .Ex -std cu
 .Sh SEE ALSO
+.Xr sysctl 2 ,
+.Xr cua 4 ,
 .Xr remote 5
 .Sh HISTORY
 The
index a268405..25d7423 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: cu.c,v 1.28 2019/06/28 13:35:00 deraadt Exp $ */
+/* $OpenBSD: cu.c,v 1.29 2023/10/02 14:48:11 krw Exp $ */
 
 /*
  * Copyright (c) 2012 Nicholas Marriott <nicm@openbsd.org>
  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
+#include <sys/types.h>
 #include <sys/ioctl.h>
+#include <sys/sysctl.h>
 
 #include <ctype.h>
 #include <err.h>
+#include <errno.h>
 #include <event.h>
 #include <fcntl.h>
 #include <getopt.h>
@@ -64,6 +67,8 @@ void          stream_error(struct bufferevent *, short, void *);
 void           line_read(struct bufferevent *, void *);
 void           line_error(struct bufferevent *, short, void *);
 void           try_remote(const char *, const char *, const char *);
+char           *get_ucomnames(void);
+char           *find_ucom(const char *, char *);
 
 __dead void
 usage(void)
@@ -78,9 +83,11 @@ int
 main(int argc, char **argv)
 {
        const char      *errstr;
-       char            *tmp, *s, *host;
+       char            *tmp, *s, *host, *ucomnames;
        int              opt, i, flags;
 
+       ucomnames = get_ucomnames();
+
        if (pledge("stdio rpath wpath cpath getpw proc exec tty",
            NULL) == -1)
                err(1, "pledge");
@@ -166,6 +173,12 @@ main(int argc, char **argv)
        if (is_direct == -1)
                is_direct = 0;
 
+       if (strncasecmp(line_path, "usb", 3) == 0) {
+               tmp = find_ucom(line_path, ucomnames);
+               if (tmp == NULL)
+                       errx(1, "No ucom matched '%s'", line_path);
+               line_path = tmp;
+       }
        if (strchr(line_path, '/') == NULL) {
                if (asprintf(&tmp, "%s%s", _PATH_DEV, line_path) == -1)
                        err(1, "asprintf");
@@ -461,3 +474,54 @@ no_change:
                cu_err(1, "strdup");
        return (out);
 }
+
+char *
+get_ucomnames(void)
+{
+       char *names;
+       int mib[2];
+       size_t size;
+
+       mib[0] = CTL_HW;
+       mib[1] = HW_UCOMNAMES;
+       names = NULL;
+       size = 0;
+       for (;;) {
+               if (sysctl(mib, 2, NULL, &size, NULL, 0) == -1 || size == 0)
+                       err(1, "hw.ucomnames");
+               if ((names = realloc(names, size)) == NULL)
+                       err(1, NULL);
+               if (sysctl(mib, 2, names, &size, NULL, 0) != -1)
+                       break;
+               if (errno != ENOMEM)
+                       err(1, "hw.ucomnames");
+       }
+       return names;
+}
+
+char *
+find_ucom(const char *usbid, char *names)
+{
+       char *cua, *id, *ucom;
+
+       if (names == NULL)
+               return NULL;
+
+       /* names is a comma separated list of "ucom<unit#>-<usb id>". */
+       cua = NULL;
+       for (ucom = strsep(&names, ","); ucom; ucom = strsep(&names, ",")) {
+               if (*ucom == '\0' || strncasecmp(ucom, "ucom", 4))
+                       continue;
+               ucom += 4;
+               id = strchr(ucom, ':');
+               if (id == NULL)
+                       continue;
+               *id++ = '\0';
+               if (strcasecmp(id, usbid) == 0) {
+                       if (asprintf(&cua, "cuaU%s", ucom) == -1)
+                               err(1, NULL);
+                       break;
+               }
+       }
+       return cua;
+}