aboutsummaryrefslogtreecommitdiff
path: root/src/rc/broadcast.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/rc/broadcast.c')
-rw-r--r--src/rc/broadcast.c211
1 files changed, 0 insertions, 211 deletions
diff --git a/src/rc/broadcast.c b/src/rc/broadcast.c
deleted file mode 100644
index 402a9fb9..00000000
--- a/src/rc/broadcast.c
+++ /dev/null
@@ -1,211 +0,0 @@
-/*
- * broadcast.c
- * broadcast a message to every logged in user
- */
-
-/*
- * Copyright 2018 Sony Interactive Entertainment Inc.
- *
- * This file is part of OpenRC. It is subject to the license terms in
- * the LICENSE file found in the top-level directory of this
- * distribution and at https://github.com/OpenRC/openrc/blob/HEAD/LICENSE
- * This file may not be copied, modified, propagated, or distributed
- * except according to the terms contained in the LICENSE file.
- */
-#include <ctype.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/sysmacros.h>
-#include <limits.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-#include <unistd.h>
-#include <stdio.h>
-#include <utmp.h>
-#include <utmpx.h>
-#include <pwd.h>
-#include <fcntl.h>
-#include <signal.h>
-#include <setjmp.h>
-#include <paths.h>
-#include <sys/utsname.h>
-
-#include "broadcast.h"
-#include "helpers.h"
-
-#ifndef _PATH_DEV
-# define _PATH_DEV "/dev/"
-#endif
-
-static sigjmp_buf jbuf;
-
-/*
- * Alarm handler
- */
-/*ARGSUSED*/
-# ifdef __GNUC__
-static void handler(int arg __attribute__((unused)))
-# else
-static void handler(int arg)
-# endif
-{
- siglongjmp(jbuf, 1);
-}
-
-static void getuidtty(char **userp, char **ttyp)
-{
- struct passwd *pwd;
- uid_t uid;
- char *tty;
- static char uidbuf[32];
- char *ttynm = NULL;
-
- uid = getuid();
- if ((pwd = getpwuid(uid)) != NULL) {
- uidbuf[0] = 0;
- strncat(uidbuf, pwd->pw_name, sizeof(uidbuf) - 1);
- } else {
- if (uid)
- sprintf(uidbuf, "uid %d", (int) uid);
- else
- sprintf(uidbuf, "root");
- }
-
- if ((tty = ttyname(0)) != NULL) {
- const size_t plen = strlen(_PATH_DEV);
- if (strncmp(tty, _PATH_DEV, plen) == 0) {
- tty += plen;
- if (tty[0] == '/')
- tty++;
- }
- xasprintf(&ttynm, "(%s) ", tty);
- }
-
- *userp = uidbuf;
- *ttyp = ttynm;
-}
-
-/*
- * Check whether the given filename looks like a tty device.
- */
-static int file_isatty(const char *fname)
-{
- struct stat st;
- int major;
-
- if (stat(fname, &st) < 0)
- return 0;
-
- if (st.st_nlink != 1 || !S_ISCHR(st.st_mode))
- return 0;
-
- /*
- * It would be an impossible task to list all major/minors
- * of tty devices here, so we just exclude the obvious
- * majors of which just opening has side-effects:
- * printers and tapes.
- */
- major = major(st.st_dev);
- if (major == 1 || major == 2 || major == 6 || major == 9 ||
- major == 12 || major == 16 || major == 21 || major == 27 ||
- major == 37 || major == 96 || major == 97 || major == 206 ||
- major == 230)
- return 0;
- return 1;
-}
-
-/*
- * broadcast function.
- *
- * NB: Not multithread safe.
- */
-void broadcast(char *text)
-{
- char *tty;
- char *user;
- struct utsname name;
- time_t t;
- char *date;
- char *p;
- char *line = NULL;
- struct sigaction sa;
- int flags;
- char *term = NULL;
- struct utmpx *utmp;
- /*
- * These are set across the sigsetjmp call, so they can't be stored on
- * the stack, otherwise they might be clobbered.
- */
- static int fd;
- static FILE *tp;
-
- getuidtty(&user, &tty);
-
- /*
- * Get and report current hostname, to make it easier to find out
- * which machine is being shut down.
- */
- uname(&name);
-
- /* Get the time */
- time(&t);
- date = ctime(&t);
- p = strchr(date, '\n');
- if (p)
- *p = 0;
-
- xasprintf(&line, "\007\r\nBroadcast message from %s@%s %s(%s):\r\n\r\n",
- user, name.nodename, tty, date);
- free(tty);
-
- /*
- * Fork to avoid hanging in a write()
- */
- if (fork() != 0)
- return;
-
- memset(&sa, 0, sizeof(sa));
- sa.sa_handler = handler;
- sigemptyset(&sa.sa_mask);
- sigaction(SIGALRM, &sa, NULL);
-
- setutxent();
-
- while ((utmp = getutxent()) != NULL) {
- if (utmp->ut_type != USER_PROCESS || utmp->ut_user[0] == 0)
- continue;
- if (strncmp(utmp->ut_line, _PATH_DEV, strlen(_PATH_DEV)) == 0)
- xasprintf(&term, "%s", utmp->ut_line);
- else
- xasprintf(&term, "%s%s", _PATH_DEV, utmp->ut_line);
- if (strstr(term, "/../")) {
- free(term);
- continue;
- }
-
- /*
- * Open it non-delay
- */
- if (sigsetjmp(jbuf, 1) == 0) {
- alarm(2);
- flags = O_WRONLY|O_NDELAY|O_NOCTTY;
- if (file_isatty(term) && (fd = open(term, flags)) >= 0) {
- if (isatty(fd) && (tp = fdopen(fd, "w")) != NULL) {
- fputs(line, tp);
- fputs(text, tp);
- fflush(tp);
- }
- }
- }
- alarm(0);
- if (fd >= 0)
- close(fd);
- if (tp != NULL)
- fclose(tp);
- free(term);
- }
- endutxent();
- free(line);
- exit(0);
-}