diff options
Diffstat (limited to 'src/rc-logger.c')
-rw-r--r-- | src/rc-logger.c | 258 |
1 files changed, 0 insertions, 258 deletions
diff --git a/src/rc-logger.c b/src/rc-logger.c deleted file mode 100644 index 675a4d23..00000000 --- a/src/rc-logger.c +++ /dev/null @@ -1,258 +0,0 @@ -/* - rc-logger.c - Spawns a logging daemon to capture stdout and stderr so we can log - them to a buffer and/or files. - */ - -/* - * Copyright 2007 Roy Marples - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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/types.h> -#include <sys/wait.h> -#include <ctype.h> -#include <fcntl.h> -#include <signal.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <termios.h> -#include <time.h> -#include <unistd.h> - -#ifdef __linux__ -# include <pty.h> -#else -# include <libutil.h> -#endif - -#include "einfo.h" -#include "rc-logger.h" -#include "rc-misc.h" -#include "rc.h" - -#define LOGFILE RC_SVCDIR "/rc.log" -#define PERMLOG "/var/log/rc.log" -#define MOVELOG "mv " LOGFILE " " PERMLOG ".$$.tmp && cat " PERMLOG \ - ".$$.tmp >>" PERMLOG " 2>/dev/null && rm -f " PERMLOG ".$$.tmp" - -static int signal_pipe[2] = { -1, -1 }; -static int fd_stdout = -1; -static int fd_stderr = -1; -static const char *runlevel = NULL; -static bool in_escape = false; -static bool in_term = false; - -static char *logbuf = NULL; -static size_t logbuf_size = 0; -static size_t logbuf_len = 0; - -pid_t rc_logger_pid = -1; -int rc_logger_tty = -1; -bool rc_in_logger = false; - -static void write_log (int logfd, const char *buffer, size_t bytes) -{ - const char *p = buffer; - - while ((size_t) (p - buffer) < bytes) { - switch (*p) { - case '\r': - goto cont; - case '\033': - in_escape = true; - in_term = false; - goto cont; - case '\n': - in_escape = in_term = false; - break; - case '[': - if (in_escape) - in_term = true; - break; - } - - if (! in_escape) { - write (logfd, p++, 1); - continue; - } - - if (! in_term || isalpha (*p)) - in_escape = in_term = false; -cont: - p++; - } -} - -static void write_time (FILE *f, const char *s) -{ - time_t now = time (NULL); - struct tm *tm = localtime (&now); - - fprintf (f, "\nrc %s logging %s at %s\n", runlevel, s, asctime (tm)); - fflush (f); -} - -void rc_logger_close () -{ - if (signal_pipe[1] > -1) { - int sig = SIGTERM; - write (signal_pipe[1], &sig, sizeof (sig)); - close (signal_pipe[1]); - signal_pipe[1] = -1; - } - - if (rc_logger_pid > 0) - waitpid (rc_logger_pid, 0, 0); - - if (fd_stdout > -1) - dup2 (fd_stdout, STDOUT_FILENO); - if (fd_stderr > -1) - dup2 (fd_stderr, STDERR_FILENO); -} - -void rc_logger_open (const char *level) -{ - int slave_tty; - struct termios tt; - struct winsize ws; - char *buffer; - fd_set rset; - int s = 0; - size_t bytes; - int selfd; - int i; - FILE *log = NULL; - - if (! isatty (STDOUT_FILENO)) - return; - - if (! rc_conf_yesno ("rc_logger")) - return; - - if (pipe (signal_pipe) == -1) - eerrorx ("pipe: %s", strerror (errno)); - for (i = 0; i < 2; i++) - if ((s = fcntl (signal_pipe[i], F_GETFD, 0) == -1 || - fcntl (signal_pipe[i], F_SETFD, s | FD_CLOEXEC) == -1)) - eerrorx ("fcntl: %s", strerror (errno)); - - tcgetattr (STDOUT_FILENO, &tt); - ioctl (STDOUT_FILENO, TIOCGWINSZ, &ws); - - /* /dev/pts may not be available yet */ - if (openpty (&rc_logger_tty, &slave_tty, NULL, &tt, &ws)) - return; - - rc_logger_pid = fork (); - switch (rc_logger_pid) { - case -1: - eerror ("forkpty: %s", strerror (errno)); - break; - case 0: - rc_in_logger = true; - close (signal_pipe[1]); - signal_pipe[1] = -1; - - runlevel = level; - if ((log = fopen (LOGFILE, "a"))) - write_time (log, "started"); - else { - free (logbuf); - logbuf_size = RC_LINEBUFFER * 10; - logbuf = xmalloc (sizeof (char) * logbuf_size); - logbuf_len = 0; - } - - buffer = xmalloc (sizeof (char) * RC_LINEBUFFER); - selfd = rc_logger_tty > signal_pipe[0] ? rc_logger_tty : signal_pipe[0]; - while (1) { - FD_ZERO (&rset); - FD_SET (rc_logger_tty, &rset); - FD_SET (signal_pipe[0], &rset); - - if ((s = select (selfd + 1, &rset, NULL, NULL, NULL)) == -1) { - eerror ("select: %s", strerror (errno)); - break; - } - - if (s > 0) { - if (FD_ISSET (rc_logger_tty, &rset)) { - memset (buffer, 0, RC_LINEBUFFER); - bytes = read (rc_logger_tty, buffer, RC_LINEBUFFER); - write (STDOUT_FILENO, buffer, bytes); - - if (log) - write_log (fileno (log), buffer, bytes); - else { - if (logbuf_size - logbuf_len < bytes) { - logbuf_size += RC_LINEBUFFER * 10; - logbuf = xrealloc (logbuf, sizeof (char ) * - logbuf_size); - } - - memcpy (logbuf + logbuf_len, buffer, bytes); - logbuf_len += bytes; - } - } - - /* Only SIGTERMS signals come down this pipe */ - if (FD_ISSET (signal_pipe[0], &rset)) - break; - } - } - free (buffer); - if (logbuf) { - if ((log = fopen (LOGFILE, "a"))) { - write_time (log, "started"); - write_log (fileno (log), logbuf, logbuf_len); - } - free (logbuf); - } - if (log) { - write_time (log, "stopped"); - fclose (log); - } - - /* Try and cat our new logfile to a more permament location and then - * punt it */ - system (MOVELOG); - - exit (0); - default: - setpgid (rc_logger_pid, 0); - fd_stdout = dup (STDOUT_FILENO); - fd_stderr = dup (STDERR_FILENO); - dup2 (slave_tty, STDOUT_FILENO); - dup2 (slave_tty, STDERR_FILENO); - if (slave_tty != STDIN_FILENO && - slave_tty != STDOUT_FILENO && - slave_tty != STDERR_FILENO) - close (slave_tty); - close (signal_pipe[0]); - signal_pipe[0] = -1; - break; - } -} |