summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--term-utils/wall.113
-rw-r--r--term-utils/wall.c91
2 files changed, 68 insertions, 36 deletions
diff --git a/term-utils/wall.1 b/term-utils/wall.1
index 4d2a9f7c1..9bf3b2653 100644
--- a/term-utils/wall.1
+++ b/term-utils/wall.1
@@ -33,15 +33,17 @@
.\"
.\" Modified for Linux, Mon Mar 8 18:07:38 1993, faith@cs.unc.edu
.\"
-.TH WALL "1" "September 2011" "util-linux" "User Commands"
+.TH WALL "1" "August 2013" "util-linux" "User Commands"
.SH NAME
wall \- write a message to users
.SH SYNOPSIS
.B wall
-[-n] [-t TIMEOUT] [file]
+[-n] [-t TIMEOUT] [file | message]
.SH DESCRIPTION
.B Wall
-displays the contents of
+displays a
+.I message
+or contents of
.I file
or, by default, its standard input, on the terminals of all currently logged
in users. The command will cut over 79 character long lines to new lines.
@@ -51,8 +53,9 @@ always put carriage return and new line at the end of each line.
Only the superuser can write on the terminals of users who have chosen to
deny messages or are using a program which automatically denies messages.
.PP
-Reading from a file is refused when the invoker is not superuser and the
-program is suid or sgid.
+Reading from a
+.I file
+is refused when the invoker is not superuser and the program is suid or sgid.
.SH OPTIONS
.TP
\fB\-n\fR, \fB\-\-nobanner\fR
diff --git a/term-utils/wall.c b/term-utils/wall.c
index 4865ac7a1..6e767ba8a 100644
--- a/term-utils/wall.c
+++ b/term-utils/wall.c
@@ -73,14 +73,15 @@
#define WRITE_TIME_OUT 300 /* in seconds */
/* Function prototypes */
-char *makemsg(char *fname, size_t *mbufsize, int print_banner);
-static void usage(FILE *out);
+static char *makemsg(char *fname, char **mvec, int mvecsz,
+ size_t *mbufsize, int print_banner);
static void __attribute__((__noreturn__)) usage(FILE *out)
{
fputs(_("\nUsage:\n"), out);
fprintf(out,
- _(" %s [options] [<file>]\n"),program_invocation_short_name);
+ _(" %s [options] [<file> | <message>]\n"),
+ program_invocation_short_name);
fputs(_("\nOptions:\n"), out);
fputs(_(" -n, --nobanner do not print banner, works only for root\n"
@@ -99,9 +100,11 @@ main(int argc, char **argv) {
char *p;
char line[sizeof(utmpptr->ut_line) + 1];
int print_banner = TRUE;
- char *mbuf;
+ char *mbuf, *fname = NULL;
size_t mbufsize;
unsigned timeout = WRITE_TIME_OUT;
+ char **mvec = NULL;
+ int mvecsz = 0;
static const struct option longopts[] = {
{ "nobanner", no_argument, 0, 'n' },
@@ -141,10 +144,15 @@ main(int argc, char **argv) {
}
argc -= optind;
argv += optind;
- if (argc > 1)
- usage(stderr);
- mbuf = makemsg(*argv, &mbufsize, print_banner);
+ if (argc == 1 && access(argv[0], F_OK) == 0)
+ fname = argv[0];
+ else if (argc >= 1) {
+ mvec = argv;
+ mvecsz = argc;
+ }
+
+ mbuf = makemsg(fname, mvec, mvecsz, &mbufsize, print_banner);
iov.iov_base = mbuf;
iov.iov_len = mbufsize;
@@ -173,8 +181,7 @@ main(int argc, char **argv) {
exit(EXIT_SUCCESS);
}
-char *
-makemsg(char *fname, size_t *mbufsize, int print_banner)
+static char *makemsg(char *fname, char **mvec, int mvecsz, size_t *mbufsize, int print_banner)
{
register int ch, cnt;
struct tm *lt;
@@ -229,34 +236,56 @@ makemsg(char *fname, size_t *mbufsize, int print_banner)
}
fprintf(fp, "%79s\r\n", " ");
+ if (mvec) {
+ /*
+ * Read message from argv[]
+ */
+ int i;
+
+ for (i = 0; i < mvecsz; i++) {
+ fputs(mvec[i], fp);
+ if (i < mvecsz - 1)
+ fputc(' ', fp);
+ }
+ fputc('\r', fp);
+ fputc('\n', fp);
- if (fname) {
+ } else {
/*
- * When we are not root, but suid or sgid, refuse to read files
- * (e.g. device files) that the user may not have access to.
- * After all, our invoker can easily do "wall < file"
- * instead of "wall file".
+ * read message from <file>
*/
- uid_t uid = getuid();
- if (uid && (uid != geteuid() || getgid() != getegid()))
- errx(EXIT_FAILURE, _("will not read %s - use stdin."),
- fname);
+ if (fname) {
+ /*
+ * When we are not root, but suid or sgid, refuse to read files
+ * (e.g. device files) that the user may not have access to.
+ * After all, our invoker can easily do "wall < file"
+ * instead of "wall file".
+ */
+ uid_t uid = getuid();
+ if (uid && (uid != geteuid() || getgid() != getegid()))
+ errx(EXIT_FAILURE, _("will not read %s - use stdin."),
+ fname);
- if (!freopen(fname, "r", stdin))
- err(EXIT_FAILURE, _("cannot open %s"), fname);
- }
+ if (!freopen(fname, "r", stdin))
+ err(EXIT_FAILURE, _("cannot open %s"), fname);
+
+ }
- while (fgets(lbuf, line_max, stdin)) {
- for (cnt = 0, p = lbuf; (ch = *p) != '\0'; ++p, ++cnt) {
- if (cnt == 79 || ch == '\n') {
- for (; cnt < 79; ++cnt)
- putc(' ', fp);
- putc('\r', fp);
- putc('\n', fp);
- cnt = 0;
+ /*
+ * Read message from stdin.
+ */
+ while (fgets(lbuf, line_max, stdin)) {
+ for (cnt = 0, p = lbuf; (ch = *p) != '\0'; ++p, ++cnt) {
+ if (cnt == 79 || ch == '\n') {
+ for (; cnt < 79; ++cnt)
+ putc(' ', fp);
+ putc('\r', fp);
+ putc('\n', fp);
+ cnt = 0;
+ }
+ if (ch != '\n')
+ carefulputc(ch, fp);
}
- if (ch != '\n')
- carefulputc(ch, fp);
}
}
fprintf(fp, "%79s\r\n", " ");