diff options
author | Marc Balmer <mbalmer@cvs.openbsd.org> | 2007-11-03 15:22:55 +0000 |
---|---|---|
committer | Marc Balmer <mbalmer@cvs.openbsd.org> | 2007-11-03 15:22:55 +0000 |
commit | 2f089dff11daa9936fc599117e35ee39cf77f271 (patch) | |
tree | 87ccd46911e8742217fc6ab4607e97d313d34f57 | |
parent | 5c64f6f7434f9454799bce6568464c9e08bbbcad (diff) |
ldattach(8) is a command to attach line discipline to a tty line. It can
be used from the command line or from init(8) by adding an entry to the
/etc/ttys file. ldattach(8) can be extended to support new line disciplines.
feedback many, ok deraadt, mikeb
-rw-r--r-- | sbin/ldattach/Makefile | 10 | ||||
-rw-r--r-- | sbin/ldattach/ldattach.8 | 152 | ||||
-rw-r--r-- | sbin/ldattach/ldattach.c | 219 |
3 files changed, 381 insertions, 0 deletions
diff --git a/sbin/ldattach/Makefile b/sbin/ldattach/Makefile new file mode 100644 index 00000000000..fd297d48bf6 --- /dev/null +++ b/sbin/ldattach/Makefile @@ -0,0 +1,10 @@ +# $OpenBSD: Makefile,v 1.1 2007/11/03 15:22:54 mbalmer Exp $ + +PROG= ldattach +MAN= ldattach.8 + +CFLAGS+= -Wall -Werror + +BINDIR= /sbin + +.include <bsd.prog.mk> diff --git a/sbin/ldattach/ldattach.8 b/sbin/ldattach/ldattach.8 new file mode 100644 index 00000000000..bc56d232198 --- /dev/null +++ b/sbin/ldattach/ldattach.8 @@ -0,0 +1,152 @@ +.\" $OpenBSD: ldattach.8,v 1.1 2007/11/03 15:22:54 mbalmer Exp $ +.\" +.\" Copyright (c) 2007 Marc Balmer <mbalmer@openbsd.org> +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: November 3 2007 $ +.Dt LDATTACH 8 +.Os +.Sh NAME +.Nm ldattach +.Nd attach a line discipline to a serial line +.Sh SYNOPSIS +.Nm ldattach +.Op Fl 7dehmo +.Op Fl s Ar baudrate +.Op Fl t Ar cond +.Ar discipline +.Ar device +.Sh DESCRIPTION +.Nm +is used to attach a line discipline to a serial line to allow for in-kernel +processing of the received and/or sent data. +Depending on the line discipline being attached, one or more options may be +applied. +.Pp +.Nm +can be used from the command line or in +.Xr ttys 5 +entries to attach line disciplines at system startup time by having +.Xr init 8 +start +.Nm +on the designated interface. +.Pp +The following options are available: +.Bl -tag -width Ds +.It Fl 7 +Use 7 databits instead of 8. +.It Fl d +Do not daemonize. +.It Fl e +Use even parity. +If both +.Fl e +and +.Fl o +are given, then no parity is used (the default). +.It Fl h +Turn on RTS/CTS flow control. +By default, no flow control is done. +.It Fl m +Maintain modem control signals after closing the line. +Specifically, this disables HUPCL. +.It Fl o +Use odd parity. +If both +.Fl e +and +.Fl o +are given, then no parity is used (the default). +.It Fl s Ar baudrate +Specifies the speed of the connection. +If not specified, the default of 4800 baud is used. +.It Fl t Ar cond +.Xr nmea 4 +line discipline only. +Chooses the condition which will cause the current system time to be +immediately copied to the terminal timestamp storage for subsequent use by +.Xr nmea 4 . +Only one can be used. +.Pp +.Bl -tag -width DCDXX -offset indent -compact +.It dcd +Copy the timestamp when DCD is asserted. +.It !dcd +Copy the timestamp when DCD is deasserted. +.It cts +Copy the timestamp when CTS is asserted. +.It !cts +Copy the timestamp when CTS is deasserted. +.El +.Pp +If no condition is specified, the +.Xr nmea 4 +line discipline will timestamp on receiving the leading +.Sq $ +character of each block of NMEA sentences. +.It Ar discipline +Specifies the name of the line discipline to be attached. +.Pp +.Bl -tag -width nmeaXX -offset -indet -compact +.It nmea +Attach the +.Xr nmea 4 +line discipline. +.It slip +Attach the +.Xr sl 4 +line discipline. +.El +.It Ar device +Specifies the name of the serial line. +.Ar device +should be a string of the form +.Dq cuaXX , +or +.Dq /dev/cuaXX . +.El +.Pp +If +.Nm +was not started by +.Xr init 8 , +the line discipline can be detached by +killing off the +.Nm +process. +.Sh EXAMPLES +To start +.Nm +by using +.Xr init 8 +to attach the +.Xr nmea 4 +line discipline to +.Pa /dev/cua00 , +add a line of the following form to +.Pa /etc/ttys : +.Bd -literal -offset indent +cua00 "/sbin/ldattach nmea" unknown on +.Ed +.Sh SEE ALSO +.Xr nmea 4 , +.Xr sl 4 , +.Xr tty 4 , +.Xr ttys 5 +.Sh HISTORY +The +.Nm +command first appeared in +.Ox 4.3 . diff --git a/sbin/ldattach/ldattach.c b/sbin/ldattach/ldattach.c new file mode 100644 index 00000000000..e7fb3238f3b --- /dev/null +++ b/sbin/ldattach/ldattach.c @@ -0,0 +1,219 @@ +/* $OpenBSD: ldattach.c,v 1.1 2007/11/03 15:22:54 mbalmer Exp $ */ + +/* + * Copyright (c) 2007 Marc Balmer <mbalmer@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * A replacement for slattach(8) and nmeaattach(8) that can be used from + * the commandline or from init(8) (using entries in /etc/ttys). + */ + +#include <sys/ioctl.h> +#include <sys/ttycom.h> + +#include <err.h> +#include <errno.h> +#include <fcntl.h> +#include <paths.h> +#include <signal.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <syslog.h> +#include <termios.h> +#include <unistd.h> + +__dead void usage(void); +void coroner(int); + +volatile sig_atomic_t dying = 0; + +__dead void +usage(void) +{ + extern char *__progname; + + fprintf(stderr, "usage: %s [-7dehmo] [-s baudrate] " + "[-t cond] discipline device\n", __progname); + exit(1); +} + +int +main(int argc, char *argv[]) +{ + struct termios tty; + struct tstamps tstamps; + const char *errstr; + tcflag_t cflag = HUPCL | CS8; + sigset_t sigset; + pid_t ppid; + int ch, fd, ldisc, nodaemon = 0, speed = B4800, parity = 0; + char devname[32], *dev, *disc; + + tstamps.ts_set = tstamps.ts_clr = 0; + + if ((ppid = getppid()) == 1) + nodaemon = 1; + + while ((ch = getopt(argc, argv, "7dehmos:t:")) != -1) { + switch (ch) { + case '7': + cflag &= ~CS8; + cflag |= CS7; + break; + case 'd': + nodaemon = 1; + break; + case 'e': + if (parity != 0) + parity = 0; /* -o -e */ + else + parity = -1; /* even */ + break; + case 'h': + cflag |= CRTSCTS; + break; + case 'm': + cflag &= ~HUPCL; + break; + case 'o': + if (parity != 0) + parity = 0; /* -e -o */ + else + parity = 1; /* odd */ + break; + case 's': + speed = (int)strtonum(optarg, 50, 230400, &errstr); + if (errstr) { + if (ppid != 1) + errx(1, "speed is %s: %s", errstr, + optarg); + else + goto bail_out; + } + break; + case 't': + if (!strcasecmp(optarg, "dcd")) + tstamps.ts_set |= TIOCM_CAR; + else if (!strcasecmp(optarg, "!dcd")) + tstamps.ts_clr |= TIOCM_CAR; + else if (!strcasecmp(optarg, "cts")) + tstamps.ts_set |= TIOCM_CTS; + else if (!strcasecmp(optarg, "!cts")) + tstamps.ts_clr |= TIOCM_CTS; + else { + if (ppid != 1) + errx(1, "'%s' not supported for " + "timestamping", optarg); + else + goto bail_out; + } + break; + default: + if (ppid != -1) + usage(); + } + } + argc -= optind; + argv += optind; + + if (ppid != 1 && argc != 2) + usage(); + + disc = *argv++; + dev = *argv; + if (strncmp(_PATH_DEV, dev, sizeof(_PATH_DEV) - 1)) { + (void)snprintf(devname, sizeof(devname), + "%s%s", _PATH_DEV, dev); + dev = devname; + } + syslog(LOG_INFO, "attach %s on %s", disc, dev); + if ((fd = open(dev, O_RDWR)) < 0) + goto bail_out; + + if (!strcmp(disc, "slip")) + ldisc = SLIPDISC; + else if (!strcmp(disc, "nmea")) + ldisc = NMEADISC; + else { + syslog(LOG_ERR, "unknown line discipline %s", disc); + goto bail_out; + } + + switch (parity) { + case -1: /* even parity */ + cflag |= PARENB; + break; + case 1: /* odd parity */ + cflag |= PARENB | PARODD; + break; + } + + tty.c_cflag = CREAD | cflag; + tty.c_iflag = 0; + tty.c_lflag = 0; + tty.c_oflag = 0; + tty.c_cc[VMIN] = 1; + tty.c_cc[VTIME] = 0; + cfsetspeed(&tty, speed); + if (tcsetattr(fd, TCSADRAIN, &tty) < 0) { + if (ppid != 1) + warnx("tcsetattr"); + goto bail_out; + } + + /* setup common to all line disciplines */ + if (ioctl(fd, TIOCSDTR, 0) < 0) + warn("TIOCSDTR"); + if (ioctl(fd, TIOCSETD, &ldisc) < 0) { + syslog(LOG_ERR, "can't set the %s line discipline on %s", disc, + dev); + goto bail_out; + } + + /* line discpline specific setup */ + switch (ldisc) { + case NMEADISC: + if (ioctl(fd, TIOCSTSTAMP, &tstamps) < 0) { + warnx("TIOCSTSTAMP"); + goto bail_out; + } + break; + } + + if (!nodaemon && daemon(0, 0)) + errx(1, "can't daemonize"); + + signal(SIGHUP, coroner); + signal(SIGTERM, coroner); + + sigemptyset(&sigset); + while (!dying) + sigsuspend(&sigset); + +bail_out: + if (ppid == 1) + sleep(30); /* delay restart when called from init */ + + return 0; +} + +/* ARGSUSED */ +void +coroner(int useless) +{ + dying = 1; +} |