Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F160513066
D57018.id178008.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
11 KB
Referenced Files
None
Subscribers
None
D57018.id178008.diff
View Options
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,60 @@
#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 tmout 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 *line, int tmout,
+ 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, line, O_WRONLY | O_NONBLOCK | O_RESOLVE_BENEATH);
+ if (fd < 0 || fstat(fd, &sb) != 0) {
+ serrno = errno;
+ close(dd);
+ if (serrno == EBUSY || serrno == EACCES)
+ return (0);
+ errno = serrno;
+ return (-1);
+ }
+ close(dd);
+ if (!shout && (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,
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,14 +120,12 @@
}
cpid = fork();
if (cpid < 0) {
- (void) snprintf(errbuf, sizeof(errbuf),
- "fork: %s", strerror(errno));
(void) close(fd);
- return (errbuf);
+ return (-1);
}
if (cpid) { /* parent */
(void) close(fd);
- return (NULL);
+ return (0);
}
forked++;
/* wait at most tmout seconds */
@@ -146,18 +140,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)
+ warnx("%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;
@@ -2152,20 +2148,23 @@
while ((ut = getutxent()) != NULL) {
if (ut->ut_type != USER_PROCESS)
continue;
+ /* this is most likely an X11 session, not a tty */
+ if (ut->ut_line[0] == ':')
+ 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 +2173,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
@@ -90,20 +90,20 @@
return (-1);
}
-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 ret = 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) {
@@ -114,11 +114,7 @@
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;
+ ret = -1;
}
nvlist_destroy(nvl);
@@ -126,13 +122,14 @@
}
int
-casper_ttymsg(nvlist_t *nvlin, nvlist_t *nvlout)
+casper_ttymsg(nvlist_t *nvlin)
{
char **nvlstrs;
struct iovec *iov;
+ const char *line;
size_t iovcnt;
int tmout;
- const char *line;
+ int ret;
nvlstrs = nvlist_take_string_array(nvlin, "iov_strs", &iovcnt);
assert(iovcnt <= TTYMSG_IOV_MAX);
@@ -144,13 +141,11 @@
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");
+ ret = ttymsg(iov, iovcnt, line, tmout, true);
free(iov);
- return (0);
+ return (ret);
}
void
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Fri, Jun 26, 6:25 AM (8 h, 28 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
34345866
Default Alt Text
D57018.id178008.diff (11 KB)
Attached To
Mode
D57018: ttymsg: Overhaul
Attached
Detach File
Event Timeline
Log In to Comment