#include "pathnames.h"
#include "ttymsg.h"
+#define ERR_BUFLEN (MAXNAMLEN + 1024)
+
/*
* 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,
char *
ttymsg(struct iovec *iov, size_t iovcnt, char *line, int tmout) {
static char device[MAXNAMLEN];
- static char errbuf[MAXNAMLEN+1024];
+ static char errbuf[ERR_BUFLEN];
size_t cnt, left;
ssize_t wret;
struct iovec localiov[6];
- int fd, forked = 0, errsv;
+ int fd, forked = 0;
+ ssize_t len = 0;
- if (iovcnt > sizeof(localiov) / sizeof(localiov[0]))
- return (_("internal error: too many iov's"));
+ if (iovcnt > ARRAY_SIZE(localiov)) {
+ snprintf(errbuf, sizeof(errbuf), _("internal error: too many iov's"));
+ return errbuf;
+ }
/* The old code here rejected the line argument when it contained a '/',
saying: "A slash may be an attempt to break security...".
already. So, this test was worthless, and these days it is
also wrong since people use /dev/pts/xxx. */
- if (strlen(line) + sizeof(_PATH_DEV) + 1 > sizeof(device)) {
- sprintf(errbuf, _("excessively long line arg"));
- return (errbuf);
+ len = snprintf(device, sizeof(device), "%s%s", _PATH_DEV, line);
+ if (len < 0 || len + 1 > (ssize_t) sizeof(device)) {
+ snprintf(errbuf, sizeof(errbuf), _("excessively long line arg"));
+ return errbuf;
}
- sprintf(device, "%s%s", _PATH_DEV, line);
/*
* open will fail on slip lines or exclusive-use lines
*/
if ((fd = open(device, O_WRONLY|O_NONBLOCK, 0)) < 0) {
if (errno == EBUSY || errno == EACCES)
- return (NULL);
- if (strlen(strerror(errno)) > 1000)
- return (NULL);
- sprintf(errbuf, "%s: %m", device);
- errbuf[1024] = 0;
- return (errbuf);
+ return NULL;
+
+ len = snprintf(errbuf, sizeof(errbuf), "%s: %m", device);
+ if (len < 0 || len + 1 > (ssize_t) sizeof(errbuf))
+ snprintf(errbuf, sizeof(errbuf), _("open failed"));
+ return errbuf;
}
for (cnt = left = 0; cnt < iovcnt; ++cnt)
}
cpid = fork();
if (cpid < 0) {
- if (strlen(strerror(errno)) > 1000)
- sprintf(errbuf, _("cannot fork"));
- else {
- errsv = errno;
- sprintf(errbuf,
- _("fork: %s"), strerror(errsv));
- }
+ len = snprintf(errbuf, sizeof(errbuf), _("fork: %m"));
+ if (len < 0 || len + 1 > (ssize_t) sizeof(errbuf))
+ snprintf(errbuf, sizeof(errbuf), _("cannot fork"));
close(fd);
- return (errbuf);
+ return errbuf;
}
if (cpid) { /* parent */
close(fd);
- return (NULL);
+ return NULL;
}
forked++;
/* wait at most tmout seconds */
warn(_("write failed: %s"), device);
if (forked)
_exit(EXIT_FAILURE);
- if (strlen(strerror(errno)) > 1000)
- sprintf(errbuf, _("%s: BAD ERROR, message is "
- "far too long"), device);
- else {
- errsv = errno;
- sprintf(errbuf, "%s: %s", device,
- strerror(errsv));
- }
- errbuf[1024] = 0;
- return (errbuf);
+
+ len = snprintf(errbuf, sizeof(errbuf), "%s: %m", device);
+ if (len < 0 || len + 1 > (ssize_t) sizeof(errbuf))
+ snprintf(errbuf, sizeof(errbuf),
+ _("%s: BAD ERROR, message is "
+ "far too long"), device);
+ return errbuf;
}
if (forked)
_exit(EXIT_SUCCESS);
- return (NULL);
+ return NULL;
}