backing out to version 208 of util-vserver
[util-vserver.git] / src / vlogin.c
diff --git a/src/vlogin.c b/src/vlogin.c
deleted file mode 100644 (file)
index f42bfd3..0000000
+++ /dev/null
@@ -1,287 +0,0 @@
-// $Id: vlogin.c 2325 2006-09-21 19:42:31Z dhozac $
-
-// Copyright (C) 2006 Benedikt Böhm <hollow@gentoo.org>
-// Based on vserver-utils' vlogin program.
-//  
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation; version 2 of the License.
-//  
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//  
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-
-#ifdef HAVE_CONFIG_H
-#  include <config.h>
-#endif
-
-#include "util.h"
-#include <lib/vserver.h>
-#include <lib/fmt.h>
-
-#include <stdlib.h>
-#include <getopt.h>
-#include <stdint.h>
-#include <string.h>
-#include <errno.h>
-#include <sys/stat.h>
-#include <sys/ioctl.h>
-#include <sys/wait.h>
-#include <sys/socket.h>
-#include <termios.h>
-#include <signal.h>
-#include <pty.h>
-#include <fcntl.h>
-
-#define ENSC_WRAPPERS_PREFIX   "vlogin: "
-#define ENSC_WRAPPERS_IOCTL    1
-#define ENSC_WRAPPERS_UNISTD   1
-#define ENSC_WRAPPERS_SOCKET   1
-#define ENSC_WRAPPERS_IO       1
-#define ENSC_WRAPPERS_TERMIOS  1
-#define ENSC_WRAPPERS_FCNTL    1
-#include <wrappers.h>
-
-struct terminal {
-  int fd;                           /* terminal file descriptor */
-  struct termios term;              /* terminal settings */
-  struct winsize ws;                /* terminal size */
-  pid_t pid;                        /* terminal process id */
-  struct termios termo;             /* original terminal settings */
-  enum { TS_RESET, TS_RAW } state;  /* terminal state */
-};
-
-static struct terminal t;
-extern int wrapper_exit_code;
-
-/* set terminal to raw mode */
-static void
-terminal_raw(void)
-{
-  struct termios buf;
-
-  /* save original terminal settings */
-  Etcgetattr(STDIN_FILENO, &t.termo);
-
-  buf = t.termo;
-  
-  /* convert terminal settings to raw mode */
-  cfmakeraw(&buf);
-
-  /* apply raw terminal settings */
-  Etcsetattr(STDIN_FILENO, TCSAFLUSH, &buf);
-
-  t.state = TS_RAW;
-}
-
-/* reset terminal to original state */
-static void
-terminal_reset(void)
-{
-  if (t.state != TS_RAW)
-    return;
-
-  Etcsetattr(STDIN_FILENO, TCSAFLUSH, &t.termo);
-
-  t.state = TS_RESET;
-}
-
-/* send signal to terminal */
-static void
-terminal_kill(int sig)
-{
-  pid_t pgrp = -1;
-
-  /* try to get process group leader */
-  if (ioctl(t.fd, TIOCGPGRP, &pgrp) >= 0 &&
-      pgrp != -1 &&
-      kill(-pgrp, sig) != -1)
-    return;
-
-  /* fallback using terminal pid */
-  kill(-t.pid, sig);
-}
-
-/* redraw the terminal screen */
-static void
-terminal_redraw(void)
-{
-  /* get winsize from stdin */
-  if (ioctl(STDIN_FILENO, TIOCGWINSZ, &t.ws) == -1)
-    return;
-
-  /* set winsize in terminal */
-  ioctl(t.fd, TIOCSWINSZ, &t.ws);
-
-  /* set winsize change signal to terminal */
-  terminal_kill(SIGWINCH);
-}
-
-/* copy terminal activities */
-static void
-terminal_copy(int src, int dst)
-{
-  char buf[64];
-  ssize_t len;
-
-  /* read terminal activity */
-  len = read(src, buf, sizeof(buf));
-  if (len == -1 && errno != EINTR) {
-    perror("read()");
-    terminal_kill(SIGTERM);
-    exit(1);
-  } else if (len == -1)
-    return;
-
-  /* write activity to user */
-  EwriteAll(dst, buf, len);
-}
-
-/* shuffle all output, and reset the terminal */
-static void
-terminal_end(void)
-{
-  char buf[64];
-  ssize_t len;
-  long options;
-
-  options = Efcntl(t.fd, F_GETFL, 0) | O_NONBLOCK;
-  Efcntl(t.fd, F_SETFL, options);
-  for (;;) {
-    len = read(t.fd, buf, sizeof(buf));
-    if (len == 0 || len == -1)
-      break;
-    EwriteAll(STDOUT_FILENO, buf, len);
-  }
-
-  /* in case atexit hasn't been setup yet */
-  terminal_reset();
-}
-
-/* catch signals */
-static void
-signal_handler(int sig)
-{
-  int status;
-
-  switch(sig) {
-    /* catch interrupt */
-    case SIGINT:
-      terminal_kill(sig);
-      break;
-
-    /* terminal died */
-    case SIGCHLD:
-      terminal_end();
-      wait(&status);
-      exit(WEXITSTATUS(status));
-      break;
-
-    /* window size has changed */
-    case SIGWINCH:
-      terminal_redraw();
-      break;
-
-    default:
-      exit(0);
-  }
-
-}
-
-void do_vlogin(int argc, char *argv[], int ind)
-{
-  int slave;
-  pid_t pid;
-  int n, i;
-  fd_set rfds;
-
-  if (!isatty(0) || !isatty(1)) {
-    execvp(argv[ind], argv+ind);
-    return;
-  }
-
-  /* set terminal to raw mode */
-  terminal_raw();
-
-  /* reset terminal to its original mode */
-  atexit(terminal_reset);
-
-  /* fork new pseudo terminal */
-  if (openpty(&t.fd, &slave, NULL, NULL, NULL) == -1) {
-    perror(ENSC_WRAPPERS_PREFIX "openpty()");
-    exit(EXIT_FAILURE);
-  }
-
-  /* setup SIGCHLD here, so we're sure to get the signal */
-  signal(SIGCHLD, signal_handler);
-
-  pid = Efork();
-
-  if (pid == 0) {
-    /* we don't need the master side of the terminal */
-    close(t.fd);
-
-    /* login_tty() stupid dietlibc doesn't have it */
-    Esetsid();
-
-    Eioctl(slave, TIOCSCTTY, NULL);
-
-    Edup2(slave, 0);
-    Edup2(slave, 1);
-    Edup2(slave, 2);
-
-    if (slave > 2)
-      close(slave);
-
-    Eexecvp(argv[ind], argv+ind);
-  }
-
-  /* setup SIGINT and SIGWINCH here, as they can cause loops in the child */
-  signal(SIGWINCH, signal_handler);
-  signal(SIGINT, signal_handler);
-
-  /* save terminals pid */
-  t.pid = pid;
-
-  /* set process title for ps */
-  n = strlen(argv[0]);
-
-  for (i = 0; i < argc; i++)
-    memset(argv[i], '\0', strlen(argv[i]));
-
-  strncpy(argv[0], "login", n);
-
-  /* we want a redraw */
-  terminal_redraw();
-
-  /* main loop */
-  for (;;) {
-    /* init file descriptors for select */
-    FD_ZERO(&rfds);
-    FD_SET(STDIN_FILENO, &rfds);
-    FD_SET(t.fd, &rfds);
-    n = t.fd;
-
-    /* wait for something to happen */
-    while (select(n + 1, &rfds, NULL, NULL, NULL) == -1) {
-      if (errno == EINTR || errno == EAGAIN)
-       continue;
-      perror(ENSC_WRAPPERS_PREFIX "select()");
-      exit(wrapper_exit_code);
-    }
-
-    if (FD_ISSET(STDIN_FILENO, &rfds))
-      terminal_copy(STDIN_FILENO, t.fd);
-
-    if (FD_ISSET(t.fd, &rfds))
-      terminal_copy(t.fd, STDOUT_FILENO);
-  }
-
-  /* never get here, signal handler exits */
-}