summaryrefslogtreecommitdiffstats
path: root/term-utils/wall.c
diff options
context:
space:
mode:
authorKarel Zak2013-08-13 11:45:54 +0200
committerKarel Zak2013-08-13 11:45:54 +0200
commitcdd3cc7fa4cafde492039180bb47f27ab8422261 (patch)
tree9ebc6b4f4d00b489bd52bf26f36616e7d800dd10 /term-utils/wall.c
parentlast: add link to util-linux to last.1 (diff)
downloadkernel-qcow2-util-linux-cdd3cc7fa4cafde492039180bb47f27ab8422261.tar.gz
kernel-qcow2-util-linux-cdd3cc7fa4cafde492039180bb47f27ab8422261.tar.xz
kernel-qcow2-util-linux-cdd3cc7fa4cafde492039180bb47f27ab8422261.zip
wall: allow to specify <message> on command line
wall(1) from sysvinit supports # wall I love this company! semantic, This patch add this functionally to the util-linux wall. Signed-off-by: Karel Zak <kzak@redhat.com>
Diffstat (limited to 'term-utils/wall.c')
-rw-r--r--term-utils/wall.c91
1 files changed, 60 insertions, 31 deletions
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", " ");