busybox/util-linux/wall.c
<<
>>
Prefs
   1/* vi: set sw=4 ts=4: */
   2/*
   3 * wall - write a message to all logged-in users
   4 * Copyright (c) 2009 Bernhard Reutner-Fischer
   5 *
   6 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
   7 */
   8//config:config WALL
   9//config:       bool "wall (2.6 kb)"
  10//config:       default y
  11//config:       depends on FEATURE_UTMP
  12//config:       help
  13//config:       Write a message to all users that are logged in.
  14
  15/* Needs to be run by root or be suid root - needs to write to /dev/TTY: */
  16//applet:IF_WALL(APPLET(wall, BB_DIR_USR_BIN, BB_SUID_REQUIRE))
  17
  18//kbuild:lib-$(CONFIG_WALL) += wall.o
  19
  20//usage:#define wall_trivial_usage
  21//usage:        "[FILE]"
  22//usage:#define wall_full_usage "\n\n"
  23//usage:        "Write content of FILE or stdin to all logged-in users"
  24//usage:
  25//usage:#define wall_sample_usage
  26//usage:        "echo foo | wall\n"
  27//usage:        "wall ./mymessage"
  28
  29#include "libbb.h"
  30
  31int wall_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
  32int wall_main(int argc UNUSED_PARAM, char **argv)
  33{
  34        struct utmpx *ut;
  35        char *msg;
  36        int fd;
  37
  38        fd = STDIN_FILENO;
  39        if (argv[1]) {
  40                /* The applet is setuid.
  41                 * Access to the file must be under user's uid/gid.
  42                 */
  43                fd = xopen_as_uid_gid(argv[1], O_RDONLY, getuid(), getgid());
  44        }
  45        msg = xmalloc_read(fd, NULL);
  46        if (ENABLE_FEATURE_CLEAN_UP && argv[1])
  47                close(fd);
  48        setutxent();
  49        while ((ut = getutxent()) != NULL) {
  50                char *line;
  51                if (ut->ut_type != USER_PROCESS)
  52                        continue;
  53                line = concat_path_file("/dev", ut->ut_line);
  54                xopen_xwrite_close(line, msg);
  55                free(line);
  56        }
  57        if (ENABLE_FEATURE_CLEAN_UP) {
  58                endutxent();
  59                free(msg);
  60        }
  61        return EXIT_SUCCESS;
  62}
  63