summaryrefslogtreecommitdiffstats
path: root/remote_cmds/wall.tproj
diff options
context:
space:
mode:
Diffstat (limited to 'remote_cmds/wall.tproj')
-rw-r--r--remote_cmds/wall.tproj/Makefile16
-rw-r--r--remote_cmds/wall.tproj/ttymsg.c179
-rw-r--r--remote_cmds/wall.tproj/ttymsg.h3
-rw-r--r--remote_cmds/wall.tproj/wall.183
-rw-r--r--remote_cmds/wall.tproj/wall.c361
5 files changed, 642 insertions, 0 deletions
diff --git a/remote_cmds/wall.tproj/Makefile b/remote_cmds/wall.tproj/Makefile
new file mode 100644
index 0000000..08da621
--- /dev/null
+++ b/remote_cmds/wall.tproj/Makefile
@@ -0,0 +1,16 @@
+Project = wall
+Install_Dir = /usr/bin
+
+HFILES = ttymsg.h
+CFILES = ttymsg.c wall.c
+MANPAGES = wall.1
+
+Extra_CC_Flags = -Wall -Werror -mdynamic-no-pic
+Extra_LD_Flags = -dead_strip
+
+Extra_CC_Flags += -D__FBSDID=__RCSID
+
+include $(MAKEFILEPATH)/CoreOS/ReleaseControl/BSDCommon.make
+
+#Install_Program_Mode = 02555
+#Install_Program_Group = tty
diff --git a/remote_cmds/wall.tproj/ttymsg.c b/remote_cmds/wall.tproj/ttymsg.c
new file mode 100644
index 0000000..ce94f87
--- /dev/null
+++ b/remote_cmds/wall.tproj/ttymsg.c
@@ -0,0 +1,179 @@
+/*
+ * Copyright (c) 1989, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+
+__FBSDID("$FreeBSD: src/usr.bin/wall/ttymsg.c,v 1.12 2006/01/27 08:52:14 ume Exp $");
+
+#ifndef lint
+__attribute__((__used__))
+static const char sccsid[] = "@(#)ttymsg.c 8.2 (Berkeley) 11/16/93";
+#endif
+
+#include <sys/types.h>
+#include <sys/uio.h>
+#include <dirent.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <paths.h>
+#include <signal.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#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.).
+ */
+const char *
+ttymsg(struct iovec *iov, int iovcnt, const char *line, int tmout)
+{
+ struct iovec localiov[7];
+ ssize_t left, wret;
+ int cnt, fd;
+ static char device[MAXNAMLEN] = _PATH_DEV;
+ static char errbuf[1024];
+ char *p;
+ int forked;
+
+ forked = 0;
+ if (iovcnt > (int)(sizeof(localiov) / sizeof(localiov[0])))
+ return ("too many iov's (change code in wall/ttymsg.c)");
+
+ p = device + sizeof(_PATH_DEV) - 1;
+#ifdef __APPLE__
+ /* radar:13145432 */
+ strlcpy(p, line, sizeof(device) - (sizeof(_PATH_DEV) - 1));
+#else
+ strlcpy(p, line, sizeof(device));
+#endif
+ 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);
+ }
+
+ /*
+ * 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) {
+#ifndef __APPLE__
+ if (errno == EBUSY || errno == EACCES)
+ return (NULL);
+#endif /* !__APPLE__ */
+ (void) snprintf(errbuf, sizeof(errbuf), "%s: %s", device,
+ strerror(errno));
+ return (errbuf);
+ }
+
+ for (cnt = 0, left = 0; cnt < iovcnt; ++cnt)
+ left += iov[cnt].iov_len;
+
+ for (;;) {
+ wret = writev(fd, iov, iovcnt);
+ if (wret >= left)
+ break;
+ if (wret >= 0) {
+ left -= wret;
+ if (iov != localiov) {
+ bcopy(iov, localiov,
+ iovcnt * sizeof(struct iovec));
+ iov = localiov;
+ }
+ for (cnt = 0; (size_t)wret >= iov->iov_len; ++cnt) {
+ wret -= iov->iov_len;
+ ++iov;
+ --iovcnt;
+ }
+ if (wret) {
+ iov->iov_base = (char *)iov->iov_base + wret;
+ iov->iov_len -= wret;
+ }
+ continue;
+ }
+ if (errno == EWOULDBLOCK) {
+ int cpid;
+
+ if (forked) {
+ (void) close(fd);
+ _exit(1);
+ }
+ cpid = fork();
+ if (cpid < 0) {
+ (void) snprintf(errbuf, sizeof(errbuf),
+ "fork: %s", strerror(errno));
+ (void) close(fd);
+ return (errbuf);
+ }
+ if (cpid) { /* parent */
+ (void) close(fd);
+ return (NULL);
+ }
+ forked++;
+ /* wait at most tmout seconds */
+ (void) signal(SIGALRM, SIG_DFL);
+ (void) signal(SIGTERM, SIG_DFL); /* XXX */
+ (void) sigsetmask(0);
+ (void) alarm((u_int)tmout);
+ (void) fcntl(fd, F_SETFL, 0); /* clear O_NONBLOCK */
+ continue;
+ }
+ /*
+ * 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)
+ break;
+ (void) close(fd);
+ if (forked)
+ _exit(1);
+ (void) snprintf(errbuf, sizeof(errbuf),
+ "%s: %s", device, strerror(errno));
+ return (errbuf);
+ }
+
+ (void) close(fd);
+ if (forked)
+ _exit(0);
+ return (NULL);
+}
diff --git a/remote_cmds/wall.tproj/ttymsg.h b/remote_cmds/wall.tproj/ttymsg.h
new file mode 100644
index 0000000..625c22d
--- /dev/null
+++ b/remote_cmds/wall.tproj/ttymsg.h
@@ -0,0 +1,3 @@
+/* $FreeBSD: src/usr.bin/wall/ttymsg.h,v 1.1 2001/09/09 14:23:31 dd Exp $ */
+
+const char *ttymsg(struct iovec *, int, const char *, int);
diff --git a/remote_cmds/wall.tproj/wall.1 b/remote_cmds/wall.tproj/wall.1
new file mode 100644
index 0000000..7c92e63
--- /dev/null
+++ b/remote_cmds/wall.tproj/wall.1
@@ -0,0 +1,83 @@
+.\" Copyright (c) 1989, 1990, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)wall.1 8.1 (Berkeley) 6/6/93
+.\" $FreeBSD: src/usr.bin/wall/wall.1,v 1.11 2004/07/17 04:15:27 tjr Exp $
+.\"
+.Dd July 17, 2004
+.Dt WALL 1
+.Os
+.Sh NAME
+.Nm wall
+.Nd write a message to users
+.Sh SYNOPSIS
+.Nm
+.Op Fl g Ar group
+.Op Ar file
+.Sh DESCRIPTION
+The
+.Nm
+utility displays the contents of
+.Ar file
+or, by default, its standard input, on the terminals of all
+currently logged in users.
+.Pp
+Only the super-user can write on the
+terminals of users who have chosen
+to deny messages or are using a program which
+automatically denies messages.
+.Bl -tag -width indent
+.It Fl g
+Send messages to users in this group.
+This option may be specified
+multiple times, and any user in any of the specified groups will
+receive the message.
+.El
+.Sh SEE ALSO
+.Xr mesg 1 ,
+.Xr talk 1 ,
+.Xr write 1 ,
+.Xr shutdown 8
+.Sh HISTORY
+A
+.Nm
+command appeared in PWB UNIX.
+.Sh BUGS
+The sender's
+.Ev LC_CTYPE
+setting is used to determine which characters are safe to write to a
+terminal, not the receiver's (which
+.Nm
+has no way of knowing).
+.Pp
+The
+.Nm
+utility does not recognize multibyte characters.
diff --git a/remote_cmds/wall.tproj/wall.c b/remote_cmds/wall.tproj/wall.c
new file mode 100644
index 0000000..b856f7b
--- /dev/null
+++ b/remote_cmds/wall.tproj/wall.c
@@ -0,0 +1,361 @@
+/*
+ * Copyright (c) 1988, 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+
+__FBSDID("$FreeBSD: src/usr.bin/wall/wall.c,v 1.25 2008/01/15 07:40:30 das Exp $");
+
+#ifndef lint
+__attribute__((__used__))
+static const char copyright[] =
+"@(#) Copyright (c) 1988, 1990, 1993\n\
+ The Regents of the University of California. All rights reserved.\n";
+#endif
+
+#ifndef lint
+__attribute__((__used__))
+static const char sccsid[] = "@(#)wall.c 8.2 (Berkeley) 11/16/93";
+#endif
+
+/*
+ * This program is not related to David Wall, whose Stanford Ph.D. thesis
+ * is entitled "Mechanisms for Broadcast and Selective Broadcast".
+ */
+
+#include <sys/param.h>
+#include <sys/stat.h>
+#include <sys/uio.h>
+
+#include <ctype.h>
+#include <err.h>
+#include <grp.h>
+#include <locale.h>
+#include <paths.h>
+#include <pwd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <unistd.h>
+#ifdef __APPLE__
+#include <utmpx.h>
+#else
+#include <utmp.h>
+#endif
+
+#include "ttymsg.h"
+
+static void makemsg(char *);
+static void usage(void);
+
+struct wallgroup {
+ struct wallgroup *next;
+ char *name;
+ gid_t gid;
+} *grouplist;
+int nobanner;
+int mbufsize;
+char *mbuf;
+
+#ifndef __APPLE__
+static int
+ttystat(char *line, int sz)
+{
+ struct stat sb;
+ char ttybuf[MAXPATHLEN];
+
+ (void)snprintf(ttybuf, sizeof(ttybuf), "%s%.*s", _PATH_DEV, sz, line);
+ if (stat(ttybuf, &sb) == 0) {
+ return (0);
+ } else
+ return (-1);
+}
+#endif
+
+int
+main(int argc, char *argv[])
+{
+ struct iovec iov;
+#ifdef __APPLE__
+ // rdar://problem/4433603
+ struct utmpx *u;
+#else
+ struct utmp utmp;
+#endif
+ int ch;
+ int ingroup;
+#ifndef __APPLE__
+ FILE *fp;
+#endif
+ struct wallgroup *g;
+ struct group *grp;
+ char **np;
+ const char *p;
+ struct passwd *pw;
+#ifdef __APPLE__
+ char line[sizeof(u->ut_line) + 1];
+ char username[sizeof(u->ut_user) + 1];
+#else
+ char line[sizeof(utmp.ut_line) + 1];
+ char username[sizeof(utmp.ut_name) + 1];
+#endif
+
+ (void)setlocale(LC_CTYPE, "");
+
+ while ((ch = getopt(argc, argv, "g:n")) != -1)
+ switch (ch) {
+ case 'n':
+ /* undoc option for shutdown: suppress banner */
+ if (geteuid() == 0)
+ nobanner = 1;
+ break;
+ case 'g':
+ g = (struct wallgroup *)malloc(sizeof *g);
+ g->next = grouplist;
+ g->name = optarg;
+ g->gid = -1;
+ grouplist = g;
+ break;
+ case '?':
+ default:
+ usage();
+ }
+ argc -= optind;
+ argv += optind;
+ if (argc > 1)
+ usage();
+
+ for (g = grouplist; g; g = g->next) {
+ grp = getgrnam(g->name);
+ if (grp != NULL)
+ g->gid = grp->gr_gid;
+ else
+ warnx("%s: no such group", g->name);
+ }
+
+ makemsg(*argv);
+
+#ifdef __APPLE__
+ setutxent();
+#else
+ if (!(fp = fopen(_PATH_UTMP, "r")))
+ err(1, "cannot read %s", _PATH_UTMP);
+#endif
+ iov.iov_base = mbuf;
+ iov.iov_len = mbufsize;
+ /* NOSTRICT */
+#ifdef __APPLE__
+ while ((u = getutxent()) != NULL) {
+ if (!u->ut_user[0] || u->ut_type != USER_PROCESS)
+ continue;
+#else
+ while (fread((char *)&utmp, sizeof(utmp), 1, fp) == 1) {
+ if (!utmp.ut_name[0])
+ continue;
+ if (ttystat(utmp.ut_line, UT_LINESIZE) != 0)
+ continue;
+#endif
+ if (grouplist) {
+ ingroup = 0;
+#ifdef __APPLE__
+ strlcpy(username, u->ut_user, sizeof(username));
+#else
+ strlcpy(username, utmp.ut_name, sizeof(utmp.ut_name));
+#endif
+ pw = getpwnam(username);
+ if (!pw)
+ continue;
+ for (g = grouplist; g && ingroup == 0; g = g->next) {
+ if (g->gid == (gid_t)-1)
+ continue;
+ if (g->gid == pw->pw_gid)
+ ingroup = 1;
+ else if ((grp = getgrgid(g->gid)) != NULL) {
+ for (np = grp->gr_mem; *np; np++) {
+ if (strcmp(*np, username) == 0) {
+ ingroup = 1;
+ break;
+ }
+ }
+ }
+ }
+ if (ingroup == 0)
+ continue;
+ }
+#ifdef __APPLE__
+ strlcpy(line, u->ut_line, sizeof(line));
+#else
+ strncpy(line, utmp.ut_line, sizeof(utmp.ut_line));
+ line[sizeof(utmp.ut_line)] = '\0';
+#endif
+ if ((p = ttymsg(&iov, 1, line, 60*5)) != NULL)
+ warnx("%s", p);
+ }
+ exit(0);
+}
+
+static void
+usage()
+{
+ (void)fprintf(stderr, "usage: wall [-g group] [file]\n");
+ exit(1);
+}
+
+void
+makemsg(char *fname)
+{
+ int cnt;
+ unsigned char ch;
+ struct tm *lt;
+ struct passwd *pw;
+ struct stat sbuf;
+ time_t now;
+ FILE *fp;
+ int fd;
+ char *p, hostname[MAXHOSTNAMELEN], lbuf[256], tmpname[64];
+ const char *tty;
+ const char *whom;
+ gid_t egid;
+
+ (void)snprintf(tmpname, sizeof(tmpname), "%s/wall.XXXXXX", _PATH_TMP);
+ if ((fd = mkstemp(tmpname)) == -1 || !(fp = fdopen(fd, "r+")))
+ err(1, "can't open temporary file");
+ (void)unlink(tmpname);
+
+ if (!nobanner) {
+ tty = ttyname(STDERR_FILENO);
+ if (tty == NULL)
+ tty = "no tty";
+
+ if (!(whom = getlogin()))
+ whom = (pw = getpwuid(getuid())) ? pw->pw_name : "???";
+ (void)gethostname(hostname, sizeof(hostname));
+ (void)time(&now);
+ lt = localtime(&now);
+
+ /*
+ * all this stuff is to blank out a square for the message;
+ * we wrap message lines at column 79, not 80, because some
+ * terminals wrap after 79, some do not, and we can't tell.
+ * Which means that we may leave a non-blank character
+ * in column 80, but that can't be helped.
+ */
+ (void)fprintf(fp, "\r%79s\r\n", " ");
+ (void)snprintf(lbuf, sizeof(lbuf),
+ "Broadcast Message from %s@%s",
+ whom, hostname);
+ (void)fprintf(fp, "%-79.79s\007\007\r\n", lbuf);
+ (void)snprintf(lbuf, sizeof(lbuf),
+ " (%s) at %d:%02d %s...", tty,
+ lt->tm_hour, lt->tm_min, lt->tm_zone);
+ (void)fprintf(fp, "%-79.79s\r\n", lbuf);
+ }
+ (void)fprintf(fp, "%79s\r\n", " ");
+
+ if (fname) {
+ egid = getegid();
+ setegid(getgid());
+ if (freopen(fname, "r", stdin) == NULL)
+ err(1, "can't read %s", fname);
+ setegid(egid);
+ }
+ while (fgets(lbuf, sizeof(lbuf), stdin)) {
+ for (cnt = 0, p = lbuf; (ch = *p) != '\0'; ++p, ++cnt) {
+ if (ch == '\r') {
+ putc('\r', fp);
+ cnt = 0;
+ continue;
+ } else if (ch == '\n') {
+ for (; cnt < 79; ++cnt)
+ putc(' ', fp);
+ putc('\r', fp);
+ putc('\n', fp);
+ break;
+ }
+ if (cnt == 79) {
+ putc('\r', fp);
+ putc('\n', fp);
+ cnt = 0;
+ }
+#ifdef __APPLE__
+ else // rdar://problem/3066405
+#endif
+ if (((ch & 0x80) && ch < 0xA0) ||
+ /* disable upper controls */
+ (!isprint(ch) && !isspace(ch) &&
+ ch != '\a' && ch != '\b')
+ ) {
+ if (ch & 0x80) {
+ ch &= 0x7F;
+ putc('M', fp);
+ if (++cnt == 79) {
+ putc('\r', fp);
+ putc('\n', fp);
+ cnt = 0;
+ }
+ putc('-', fp);
+ if (++cnt == 79) {
+ putc('\r', fp);
+ putc('\n', fp);
+ cnt = 0;
+ }
+ }
+ if (iscntrl(ch)) {
+ ch ^= 040;
+ putc('^', fp);
+ if (++cnt == 79) {
+ putc('\r', fp);
+ putc('\n', fp);
+ cnt = 0;
+ }
+ }
+ }
+#ifdef __APPLE__
+ // rdar://problem/4557295
+ if (ch != '\n')
+#endif
+ putc(ch, fp);
+ }
+ }
+ (void)fprintf(fp, "%79s\r\n", " ");
+ rewind(fp);
+
+ if (fstat(fd, &sbuf))
+ err(1, "can't stat temporary file");
+ mbufsize = sbuf.st_size;
+ if (!(mbuf = malloc((u_int)mbufsize)))
+ err(1, "out of memory");
+ if ((int)fread(mbuf, sizeof(*mbuf), mbufsize, fp) != mbufsize)
+ err(1, "can't read temporary file");
+ (void)close(fd);
+}