Page MenuHomeFreeBSD

D57018.id178401.diff
No OneTemporary

D57018.id178401.diff

diff --git a/libexec/talkd/announce.c b/libexec/talkd/announce.c
--- a/libexec/talkd/announce.c
+++ b/libexec/talkd/announce.c
@@ -40,6 +40,7 @@
#include <errno.h>
#include <paths.h>
+#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -152,7 +153,7 @@
* stack up processes trying to write messages to a tty
* that is permanently blocked.
*/
- if (ttymsg(&iovec, 1, tty, RING_WAIT - 5) != NULL)
+ if (ttymsg(&iovec, 1, tty, RING_WAIT - 5, true) != 0)
return (FAILED);
return (SUCCESS);
diff --git a/usr.bin/wall/ttymsg.h b/usr.bin/wall/ttymsg.h
--- a/usr.bin/wall/ttymsg.h
+++ b/usr.bin/wall/ttymsg.h
@@ -1,4 +1,4 @@
#define TTYMSG_IOV_MAX 32
-const char *ttymsg(struct iovec *, int, const char *, int);
+int ttymsg(struct iovec *, int, const char *, int, bool);
diff --git a/usr.bin/wall/ttymsg.c b/usr.bin/wall/ttymsg.c
--- a/usr.bin/wall/ttymsg.c
+++ b/usr.bin/wall/ttymsg.c
@@ -29,15 +29,16 @@
* SUCH DAMAGE.
*/
-
-
#include <sys/types.h>
+#include <sys/stat.h>
#include <sys/uio.h>
+
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <paths.h>
#include <signal.h>
+#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
@@ -46,65 +47,72 @@
#include "ttymsg.h"
/*
- * Display the contents of a uio structure on a terminal. Used by wall(1),
- * syslogd(8), and talkd(8). Forks and finishes in child if write would block,
- * waiting up to tmout seconds. Returns pointer to error string on unexpected
- * error; string is not newline-terminated. Various "normal" errors are
- * ignored (exclusive-use, lack of permission, etc.).
+ * Display the contents of a uio structure on a terminal. If shout is
+ * non-zero, do so even if the terminal has messages disabled. Used by
+ * wall(1), syslogd(8), and talkd(8). Forks and finishes in child if
+ * write would block, waiting up to timeout seconds. Various "normal"
+ * errors are ignored (exclusive-use, lack of permission, etc.).
*/
-const char *
-ttymsg(struct iovec *iov, int iovcnt, const char *line, int tmout)
+int
+ttymsg(struct iovec *iov, int iovcnt, const char *tty, int timeout,
+ bool shout)
{
struct iovec localiov[TTYMSG_IOV_MAX];
- ssize_t left, wret;
- int cnt, fd;
- char device[MAXNAMLEN] = _PATH_DEV;
- static char errbuf[1024];
- char *p;
+ struct stat sb;
+ ssize_t wret;
+ size_t resid;
+ int cnt, dd, fd, serrno;
int forked;
forked = 0;
- if (iovcnt > (int)(sizeof(localiov) / sizeof(localiov[0])))
- return ("too many iov's (change code in wall/ttymsg.c)");
-
- strlcat(device, line, sizeof(device));
- p = device + sizeof(_PATH_DEV) - 1;
- if (strncmp(p, "pts/", 4) == 0)
- p += 4;
- if (strchr(p, '/') != NULL) {
- /* A slash is an attempt to break security... */
- (void) snprintf(errbuf, sizeof(errbuf),
- "Too many '/' in \"%s\"", device);
- return (errbuf);
+ if (iovcnt > (int)(sizeof(localiov) / sizeof(localiov[0]))) {
+ errno = EFBIG;
+ return (-1);
}
- /*
- * open will fail on slip lines or exclusive-use lines
- * if not running as root; not an error.
- */
- if ((fd = open(device, O_WRONLY|O_NONBLOCK, 0)) < 0) {
- if (errno == EBUSY || errno == EACCES)
- return (NULL);
- (void) snprintf(errbuf, sizeof(errbuf), "%s: %s", device,
- strerror(errno));
- return (errbuf);
+ dd = open(_PATH_DEV, O_SEARCH | O_DIRECTORY);
+ if (dd < 0)
+ return (-1);
+ fd = openat(dd, tty, O_WRONLY | O_NONBLOCK | O_RESOLVE_BENEATH);
+ if (fd < 0) {
+ serrno = errno;
+ close(dd);
+ /*
+ * open will fail on slip lines or exclusive-use lines
+ * if not running as root; not an error.
+ */
+ if (serrno == EBUSY || serrno == EACCES)
+ return (0);
+ errno = serrno;
+ return (-1);
+ }
+ close(dd);
+ if (!shout) {
+ if (fstat(fd, &sb) != 0) {
+ serrno = errno;
+ close(fd);
+ errno = serrno;
+ return (-1);
+ }
+ if ((sb.st_mode & S_IWGRP) == 0) {
+ close(fd);
+ return (0);
+ }
}
- for (cnt = 0, left = 0; cnt < iovcnt; ++cnt)
- left += iov[cnt].iov_len;
+ for (cnt = 0, resid = 0; cnt < iovcnt; ++cnt)
+ resid += iov[cnt].iov_len;
- for (;;) {
+ do {
wret = writev(fd, iov, iovcnt);
- if (wret >= left)
- break;
if (wret >= 0) {
- left -= wret;
+ resid -= wret;
if (iov != localiov) {
- bcopy(iov, localiov,
+ bcopy(iov, localiov,
iovcnt * sizeof(struct iovec));
iov = localiov;
}
- for (cnt = 0; (size_t)wret >= iov->iov_len; ++cnt) {
+ while ((size_t)wret >= iov->iov_len) {
wret -= iov->iov_len;
++iov;
--iovcnt;
@@ -124,21 +132,21 @@
}
cpid = fork();
if (cpid < 0) {
- (void) snprintf(errbuf, sizeof(errbuf),
- "fork: %s", strerror(errno));
+ serrno = errno;
(void) close(fd);
- return (errbuf);
+ errno = serrno;
+ return (-1);
}
if (cpid) { /* parent */
(void) close(fd);
- return (NULL);
+ return (0);
}
forked++;
- /* wait at most tmout seconds */
+ /* wait at most timeout seconds */
(void) signal(SIGALRM, SIG_DFL);
(void) signal(SIGTERM, SIG_DFL); /* XXX */
(void) sigsetmask(0);
- (void) alarm((u_int)tmout);
+ (void) alarm((u_int)timeout);
(void) fcntl(fd, F_SETFL, 0); /* clear O_NONBLOCK */
continue;
}
@@ -146,18 +154,18 @@
* We get ENODEV on a slip line if we're running as root,
* and EIO if the line just went away.
*/
- if (errno == ENODEV || errno == EIO)
+ serrno = errno;
+ if (serrno == ENODEV || serrno == EIO)
break;
(void) close(fd);
if (forked)
_exit(1);
- (void) snprintf(errbuf, sizeof(errbuf),
- "%s: %s", device, strerror(errno));
- return (errbuf);
- }
+ errno = serrno;
+ return (-1);
+ } while (resid > 0);
(void) close(fd);
if (forked)
_exit(0);
- return (NULL);
+ return (0);
}
diff --git a/usr.bin/wall/wall.c b/usr.bin/wall/wall.c
--- a/usr.bin/wall/wall.c
+++ b/usr.bin/wall/wall.c
@@ -44,6 +44,7 @@
#include <locale.h>
#include <paths.h>
#include <pwd.h>
+#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -90,7 +91,6 @@
struct wallgroup *g;
struct group *grp;
char **np;
- const char *p;
struct passwd *pw;
(void)setlocale(LC_CTYPE, "");
@@ -158,8 +158,8 @@
if (ingroup == 0)
continue;
}
- if ((p = ttymsg(&iov, 1, utmp->ut_line, 60*5)) != NULL)
- warnx("%s", p);
+ if (ttymsg(&iov, 1, utmp->ut_line, 60 * 5, 1) != 0)
+ warn("%s", utmp->ut_line);
}
exit(0);
}
diff --git a/usr.sbin/syslogd/syslogd.c b/usr.sbin/syslogd/syslogd.c
--- a/usr.sbin/syslogd/syslogd.c
+++ b/usr.sbin/syslogd/syslogd.c
@@ -360,7 +360,6 @@
static nvlist_t *prop_filter_compile(const char *);
static void parsemsg(const char *, char *);
static void printsys(char *);
-static const char *ttymsg_check(struct iovec *, int, char *, int);
static void usage(void);
static bool validate(struct sockaddr *, const char *);
static void unmapped(struct sockaddr *);
@@ -1756,8 +1755,6 @@
static void
fprintlog_write(struct filed *f, struct iovlist *il, int flags)
{
- const char *msgret;
-
switch (f->f_type) {
case F_FORW: {
ssize_t lsent;
@@ -1910,10 +1907,10 @@
dprintf(" %s%s\n", _PATH_DEV, f->f_fname);
iovlist_append(il, "\r\n");
errno = 0; /* ttymsg() only sometimes returns an errno */
- if ((msgret = cap_ttymsg(cap_syslogd, il->iov, il->iovcnt,
- f->f_fname, 10))) {
+ if (cap_ttymsg(cap_syslogd, il->iov, il->iovcnt, f->f_fname, 10,
+ true) != 0) {
f->f_type = F_UNUSED;
- logerror(msgret);
+ logerror(f->f_fname);
}
break;
@@ -2143,7 +2140,6 @@
static int reenter; /* avoid calling ourselves */
struct utmpx *ut;
int i;
- const char *p;
if (reenter++)
return;
@@ -2153,19 +2149,19 @@
if (ut->ut_type != USER_PROCESS)
continue;
if (f->f_type == F_WALL) {
- if ((p = ttymsg(iov, iovlen, ut->ut_line,
- TTYMSGTIME)) != NULL)
- dprintf("%s\n", p);
+ if (ttymsg(iov, iovlen, ut->ut_line, TTYMSGTIME,
+ false) != 0 && errno != ENOENT)
+ dprintf("%s: %m\n", ut->ut_line);
continue;
}
/* should we send the message to this user? */
for (i = 0; i < MAXUNAMES; i++) {
if (!f->f_uname[i][0])
break;
- if (!strcmp(f->f_uname[i], ut->ut_user)) {
- if ((p = ttymsg_check(iov, iovlen, ut->ut_line,
- TTYMSGTIME)) != NULL)
- dprintf("%s\n", p);
+ if (strcmp(f->f_uname[i], ut->ut_user) == 0) {
+ if (ttymsg(iov, iovlen, ut->ut_line, TTYMSGTIME,
+ true) != 0 && errno != ENOENT)
+ dprintf("%s: %m\n", ut->ut_line);
break;
}
}
@@ -2174,29 +2170,6 @@
reenter = 0;
}
-/*
- * Wrapper routine for ttymsg() that checks the terminal for messages enabled.
- */
-static const char *
-ttymsg_check(struct iovec *iov, int iovcnt, char *line, int tmout)
-{
- static char device[1024];
- static char errbuf[1024];
- struct stat sb;
-
- (void) snprintf(device, sizeof(device), "%s%s", _PATH_DEV, line);
-
- if (stat(device, &sb) < 0) {
- (void) snprintf(errbuf, sizeof(errbuf),
- "%s: %s", device, strerror(errno));
- return (errbuf);
- }
- if ((sb.st_mode & S_IWGRP) == 0)
- /* Messages disabled. */
- return (NULL);
- return (ttymsg(iov, iovcnt, line, tmout));
-}
-
/*
* Return a printable representation of a host address.
*/
diff --git a/usr.sbin/syslogd/syslogd_cap.h b/usr.sbin/syslogd/syslogd_cap.h
--- a/usr.sbin/syslogd/syslogd_cap.h
+++ b/usr.sbin/syslogd/syslogd_cap.h
@@ -62,13 +62,13 @@
int cap_p_open(cap_channel_t *, size_t, const char *, int *);
nvlist_t *cap_readconfigfile(cap_channel_t *, const char *);
-const char *cap_ttymsg(cap_channel_t *, struct iovec *, int, const char *, int);
+int cap_ttymsg(cap_channel_t *, struct iovec *, int, const char *, int, bool);
void cap_wallmsg(cap_channel_t *, const struct filed *, struct iovec *,
const int);
int casper_p_open(nvlist_t *, nvlist_t *);
int casper_readconfigfile(nvlist_t *, nvlist_t *);
-int casper_ttymsg(nvlist_t *, nvlist_t *);
+int casper_ttymsg(nvlist_t *);
int casper_wallmsg(nvlist_t *);
nvlist_t *filed_to_nvlist(const struct filed *);
diff --git a/usr.sbin/syslogd/syslogd_cap.c b/usr.sbin/syslogd/syslogd_cap.c
--- a/usr.sbin/syslogd/syslogd_cap.c
+++ b/usr.sbin/syslogd/syslogd_cap.c
@@ -50,7 +50,7 @@
else if (strcmp(cmd, "readconfigfile") == 0)
error = casper_readconfigfile(nvlin, nvlout);
else if (strcmp(cmd, "ttymsg") == 0)
- error = casper_ttymsg(nvlin, nvlout);
+ error = casper_ttymsg(nvlin);
else if (strcmp(cmd, "wallmsg") == 0)
error = casper_wallmsg(nvlin);
diff --git a/usr.sbin/syslogd/syslogd_cap_log.c b/usr.sbin/syslogd/syslogd_cap_log.c
--- a/usr.sbin/syslogd/syslogd_cap_log.c
+++ b/usr.sbin/syslogd/syslogd_cap_log.c
@@ -52,14 +52,12 @@
exit(1);
}
error = nvlist_get_number(nvl, "error");
- if (error != 0) {
- errno = error;
- logerror("Failed to open piped command");
- }
pipedesc_w = dnvlist_take_descriptor(nvl, "pipedesc_w", -1);
*procdesc = dnvlist_take_descriptor(nvl, "procdesc", -1);
nvlist_destroy(nvl);
+ if (error != 0)
+ errno = error;
return (pipedesc_w);
}
@@ -81,29 +79,27 @@
pipedesc_w = p_open(prog, &procdesc);
if (pipedesc_w == -1)
- return (-1);
+ return (errno);
nvlist_move_descriptor(nvlout, "pipedesc_w", pipedesc_w);
nvlist_move_descriptor(nvlout, "procdesc", procdesc);
return (0);
}
-
- return (-1);
+ return (ECAPMODE);
}
-const char *
+int
cap_ttymsg(cap_channel_t *chan, struct iovec *iov, int iovcnt,
- const char *line, int tmout)
+ const char *line, int tmout, bool shout)
{
nvlist_t *nvl = nvlist_create(0);
- int error;
- static char errbuf[1024];
- char *ret = NULL;
+ int error = 0;
nvlist_add_string(nvl, "cmd", "ttymsg");
for (int i = 0; i < iovcnt; ++i)
nvlist_append_string_array(nvl, "iov_strs", iov[i].iov_base);
nvlist_add_string(nvl, "line", line);
- nvlist_add_number(nvl, "tmout", tmout);
+ nvlist_add_number(nvl, "timeout", tmout);
+ nvlist_add_bool(nvl, "shout", shout);
nvl = cap_xfer_nvlist(chan, nvl);
if (nvl == NULL) {
@@ -111,28 +107,23 @@
exit(1);
}
error = nvlist_get_number(nvl, "error");
+ nvlist_destroy(nvl);
if (error != 0) {
errno = error;
- logerror("Failed to ttymsg");
- }
- if (nvlist_exists_string(nvl, "errstr")) {
- const char *errstr = nvlist_get_string(nvl, "errstr");
- (void)strlcpy(errbuf, errstr, sizeof(errbuf));
- ret = errbuf;
+ return (-1);
}
-
- nvlist_destroy(nvl);
- return (ret);
+ return (0);
}
int
-casper_ttymsg(nvlist_t *nvlin, nvlist_t *nvlout)
+casper_ttymsg(nvlist_t *nvlin)
{
char **nvlstrs;
struct iovec *iov;
- size_t iovcnt;
- int tmout;
const char *line;
+ size_t iovcnt;
+ int ret, tmout;
+ bool shout;
nvlstrs = nvlist_take_string_array(nvlin, "iov_strs", &iovcnt);
assert(iovcnt <= TTYMSG_IOV_MAX);
@@ -144,13 +135,12 @@
iov[i].iov_len = strlen(nvlstrs[i]);
}
line = nvlist_get_string(nvlin, "line");
- tmout = nvlist_get_number(nvlin, "tmout");
- line = ttymsg(iov, iovcnt, line, tmout);
- if (line != NULL)
- nvlist_add_string(nvlout, "errstr", line);
-
+ tmout = nvlist_get_number(nvlin, "timeout");
+ shout = nvlist_get_bool(nvlin, "shout");
+ if ((ret = ttymsg(iov, iovcnt, line, tmout, shout)) != 0)
+ ret = errno;
free(iov);
- return (0);
+ return (ret);
}
void
@@ -158,7 +148,6 @@
int iovcnt)
{
nvlist_t *nvl = nvlist_create(0);
- int error;
nvlist_add_string(nvl, "cmd", "wallmsg");
/*
@@ -175,11 +164,6 @@
logerror("Failed to xfer wallmsg nvlist");
exit(1);
}
- error = nvlist_get_number(nvl, "error");
- if (error != 0) {
- errno = error;
- logerror("Failed to wallmsg");
- }
nvlist_destroy(nvl);
}

File Metadata

Mime Type
text/plain
Expires
Fri, Jun 26, 7:44 AM (22 h, 22 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
34348843
Default Alt Text
D57018.id178401.diff (13 KB)

Event Timeline