Run our TTYs with our own tty runner
authorChristian Hofstaedtler <ch@grml.org>
Sun, 21 Aug 2011 15:36:28 +0000 (17:36 +0200)
committerChristian Hofstaedtler <ch@grml.org>
Sun, 21 Aug 2011 16:01:39 +0000 (18:01 +0200)
This should fix most of our environment problems. It's a bit saddening
that current Linux still tries to emulate typewriters, and we have to
deal with this shit. Therefore we deal with it like in ancient times.

compile/Makefile
compile/grml-runtty.c [new file with mode: 0644]
debian/dirs
debian/rules
manpages/grml-scripts.1
usr_bin/grml-init [deleted file]
usr_bin/grml-init-screen [deleted file]
usr_share/run-multitail [moved from usr_bin/grml-init-multitail with 62% similarity]
usr_share/run-screen [new file with mode: 0755]
usr_share/run-welcome [moved from usr_bin/zsh-login with 99% similarity]

index b45a92f..912ebe2 100644 (file)
@@ -1,4 +1,4 @@
-PROGS = pong vmware-detect align dpkg_not_running reread_partition_table
+PROGS = pong vmware-detect align dpkg_not_running reread_partition_table grml-runtty
 
 #ifndef CFLAGS
 CFLAGS = -O2 -Wall -s
@@ -28,5 +28,8 @@ align: align.c
 reread_partition_table: reread_partition_table.c
        diet $(CC) $(CFLAGS) -o $@ $^
 
+grml-runtty: grml-runtty.c
+       $(CC) $(CFLAGS) -o $@ $^
+
 clean:
        rm -f $(PROGS)
diff --git a/compile/grml-runtty.c b/compile/grml-runtty.c
new file mode 100644 (file)
index 0000000..56dcd52
--- /dev/null
@@ -0,0 +1,132 @@
+/*
+ * Copyright 2011 Christian Hofstaedtler. Licensed under GPL Version 2.
+ *
+ * Most of this is copied from fgetty, which is
+ *   Copyright Felix von Leitner, licensed under GPL Version 2.
+*/
+
+#define _GNU_SOURCE
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <pwd.h>
+#include <grp.h>
+#include <sys/param.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <syslog.h>
+#include <signal.h>
+
+char* tty;
+char* prog;
+char* user;
+
+void error(const char* message, int exitcode) {
+  write(2, "E: ", 3);
+  write(2, message, strlen(message));
+  write(2, "\n", 1);
+  syslog(LOG_CRIT, "%s", message);
+  sleep(15);
+  closelog();
+  exit(exitcode);
+}
+
+void sigquit_handler(int signum) {
+  error("SIGQUIT received\n",23);
+}
+
+void setup_tty() {
+  struct sigaction sa;
+  int fd;
+  if (chown(tty,0,0) || chmod(tty,0600))
+    error("could not chown/chmod tty device\n",1);
+  sa.sa_handler=SIG_IGN;
+  sa.sa_flags=0;
+  sigemptyset(&sa.sa_mask);
+  sigaction(SIGHUP,&sa,NULL);
+  sa.sa_handler=sigquit_handler;
+  sigaction(SIGQUIT,&sa,NULL);
+
+  setsid();
+  if ((fd=open(tty, O_RDWR, 0))<0)
+    error("open tty failed", errno);
+  if (ioctl (fd, TIOCSCTTY, (void *)1) == -1)
+    error("ioctl TIOCSCTTY failed", errno);
+  if (!isatty(fd))
+    error("\"not a typewriter\" (isatty failed)", errno);
+  if (vhangup())       /* linux specific */
+    error("vhangup failed", errno);
+  close(2); close(1); close(0); close(fd);
+  if (open(tty, O_RDWR,0) != 0)
+    error("could not (re)open tty", errno);
+  if (dup(0) != 1 || dup(0) != 2)
+    error("could not dup stdout and stderr", errno);
+
+  sa.sa_handler=SIG_DFL;
+  sa.sa_flags=0;
+  sigemptyset(&sa.sa_mask);
+  sigaction(SIGHUP,&sa,NULL);
+}
+
+void setenvvar(char* envvar, char* value) {
+  /* buf ends up directly in env. can't use alloca */
+  char* buf = malloc(strlen(envvar) + strlen(value) + 2);
+  strcpy(buf, envvar);
+  strcat(buf, "=");
+  strcat(buf, value);
+  putenv(buf);
+}
+
+int main(int argc, char* argv[]) {
+  struct passwd* pw;
+
+  tty = argv[1];
+  prog = argv[2];
+  user = argv[3];
+
+  openlog("startprog", LOG_CONS | LOG_PID, LOG_AUTHPRIV);
+
+  if (tty == NULL || prog == NULL || user == NULL)
+    error("Usage: startprog /dev/ttyX /bin/bash user", 1);
+
+  pw = getpwnam(user);
+  if (!pw)
+    error("User does not exist", 1);
+
+  clearenv();
+  putenv("TERM=linux");
+  setenvvar("TTY", tty);
+  setenvvar("USER", pw->pw_name);
+  setenvvar("LOGNAME", pw->pw_name);
+  setenvvar("SHELL", pw->pw_shell);
+  setenvvar("HOME", pw->pw_dir);
+  {
+    char uidbuf[15];
+    sprintf(uidbuf, "%i", pw->pw_uid);
+    setenvvar("UID", uidbuf);
+  }
+
+#ifndef DEBUG
+  setup_tty();
+#endif
+  chown(tty, pw->pw_uid, pw->pw_gid);
+
+  if (initgroups(pw->pw_name, pw->pw_gid) == -1)
+    error("initgroups failed", 1);
+  if (setgid(pw->pw_gid) == -1)
+    error("setgid failed", 1);
+  if (setuid(pw->pw_uid) == -1)
+    error("setuid failed", 1);
+
+  {
+    char *Argv[] = {prog, 0};
+    execve(prog, Argv, environ);
+  }
+
+  /* should never come here */
+  error("Program startup failed", 99);
+}
index a2c53cc..978ffc6 100644 (file)
@@ -1,5 +1,6 @@
 etc/grml
 etc/postfix
+sbin
 usr/bin
 usr/sbin
 usr/share/grml-scripts
index fa07537..aa076ba 100755 (executable)
@@ -41,6 +41,7 @@ install: build
        install -m 755 compile/vmware-detect          debian/grml-scripts/usr/bin/vmware-detect
        install -m 755 compile/dpkg_not_running       debian/grml-scripts/usr/sbin/dpkg_not_running
        install -m 755 compile/reread_partition_table debian/grml-scripts/usr/sbin/reread_partition_table
+       install -m 755 compile/grml-runtty             debian/grml-scripts/sbin/grml-runtty
 
 # Build architecture-independent files here.
 binary-indep: build install
@@ -92,13 +93,13 @@ binary-arch: build install
                /usr/share/man/man1/grml-scripts.1.gz /usr/share/man/man1/grml-hostname.1.gz \
                /usr/share/man/man1/grml-scripts.1.gz /usr/share/man/man1/grml-info.1.gz \
                /usr/share/man/man1/grml-scripts.1.gz /usr/share/man/man1/grml-init.1.gz \
-               /usr/share/man/man1/grml-scripts.1.gz /usr/share/man/man1/grml-init-screen.1.gz \
                /usr/share/man/man1/grml-scripts.1.gz /usr/share/man/man1/grml-lock.1.gz \
                /usr/share/man/man1/grml-scripts.1.gz /usr/share/man/man1/grml-mutt.1.gz \
                /usr/share/man/man1/grml-scripts.1.gz /usr/share/man/man1/grml-postfix.1.gz \
                /usr/share/man/man1/grml-scripts.1.gz /usr/share/man/man1/grml-soundtest.1.gz \
                /usr/share/man/man1/grml-scripts.1.gz /usr/share/man/man1/grml-lang.1.gz \
                /usr/share/man/man1/grml-scripts.1.gz /usr/share/man/man1/grml-resolution.1.gz \
+               /usr/share/man/man1/grml-scripts.1.gz /usr/share/man/man1/grml-runtty.1.gz \
                /usr/share/man/man1/grml-scripts.1.gz /usr/share/man/man1/grml-slrn.1.gz \
                /usr/share/man/man1/grml-scripts.1.gz /usr/share/man/man1/grml-start.1.gz \
                /usr/share/man/man1/grml-scripts.1.gz /usr/share/man/man1/grml-tpm.1.gz \
@@ -139,7 +140,6 @@ binary-arch: build install
                /usr/share/man/man1/grml-scripts.1.gz /usr/share/man/man1/XF86AudioLowerVolume.1.gz \
                /usr/share/man/man1/grml-scripts.1.gz /usr/share/man/man1/XF86AudioMute.1.gz \
                /usr/share/man/man1/grml-scripts.1.gz /usr/share/man/man1/XF86AudioRaiseVolume.1.gz \
-               /usr/share/man/man1/grml-scripts.1.gz /usr/share/man/man1/zsh-login.1.gz \
                /usr/share/man/man1/gsuggest.1.gz     /usr/share/man/man1/gsuggest.pl.1.gz
        dh_strip
        dh_compress
index 535055b..23d2f3f 100644 (file)
@@ -54,15 +54,14 @@ Configuration interface for user tasks on the Grml system.
 collect hardware information and write it to info.tar.bz2
 .SS grml-info
 start browser with documentation for Grml
-.SS grml-init
-fix tty permissions and run screen and zsh (notice: not required for
-interactive usage but only for startup of Grml system)
 .SS grml-lock
 lock virtual consoles
 .SS grml-mutt
 configuration script for mailclient mutt
 .SS grml-resolution
 change X resolution via a simple menu frontend
+.SS grml-runtty
+runs arbitrary programs on the specified tty
 .SS grml-lang
 switch keyboard layout
 .SS grml-slrn
@@ -121,8 +120,6 @@ Mute and - if run again - restore audio settings.
 Raise audio volume.
 .SS xsay
 output X clipboard text via flite (soundsystem)
-.SS zsh-login
-Start zsh using login-option through exec.
 
 .SH "ADMIN SCRIPTS"
 
diff --git a/usr_bin/grml-init b/usr_bin/grml-init
deleted file mode 100755 (executable)
index 6370a53..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-#!/bin/dash
-# Filename:      grml-init
-# Purpose:       fix tty permissions and run zsh
-# Authors:       grml-team (grml.org), (c) Michael Prokop <mika@grml.org>
-# Bug-Reports:   see http://grml.org/bugs/
-# License:       This file is licensed under the GPL v2.
-################################################################################
-
-# export variable USER for use withing GNU screen:
-  export USER=`id -un`
-
-# fix rungetty:
-  TTY=`tty`
-  sudo chown $USER.$USER $TTY
-
-# now start the shell:
-  exec /bin/zsh
-
-## END OF FILE #################################################################
diff --git a/usr_bin/grml-init-screen b/usr_bin/grml-init-screen
deleted file mode 100755 (executable)
index 20587d8..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-#!/bin/dash
-# Filename:      grml-init-screen
-# Purpose:       fix tty permissions and run screen and zsh afterwards
-# Authors:       grml-team (grml.org), (c) Michael Prokop <mika@grml.org>
-# Bug-Reports:   see http://grml.org/bugs/
-# License:       This file is licensed under the GPL v2.
-################################################################################
-
-# export variable USER for use withing GNU screen:
-  export USER=`id -un`
-
-# fix rungetty:
-  TTY=`tty`
-  sudo chmod 660       $TTY
-  sudo chown $USER.tty $TTY
-
-# now start screen:
-  cd $HOME
-  # do we have a utf8 enabled terminal?
-  /usr/bin/screen -U -c /etc/grml/screenrc ; exec /bin/zsh
-
-## END OF FILE #################################################################
similarity index 62%
rename from usr_bin/grml-init-multitail
rename to usr_share/run-multitail
index 20494fa..1aa2abc 100755 (executable)
@@ -1,20 +1,12 @@
 #!/bin/dash
 # Filename:      grml-init-multitail
-# Purpose:       fix tty permissions and run multitail
+# Purpose:       run multitail
 # Authors:       grml-team (grml.org), (c) Michael Prokop <mika@grml.org>,
 #                (c) Michael Gebetsroither <gebi@grml.org>
 # Bug-Reports:   see http://grml.org/bugs/
 # License:       This file is licensed under the GPL v2.
 ################################################################################
 
-# export variable USER for use withing GNU screen:
-  export USER=`id -un`
-
-# fix rungetty:
-  TTY=`tty`
-  sudo chown $USER.$USER $TTY
-
-# now start the shell:
-  exec /usr/bin/multitail -o 'check_mail:0' /var/log/syslog
+exec /usr/bin/multitail -o 'check_mail:0' /var/log/syslog
 
 ## END OF FILE #################################################################
diff --git a/usr_share/run-screen b/usr_share/run-screen
new file mode 100755 (executable)
index 0000000..d101fc6
--- /dev/null
@@ -0,0 +1,23 @@
+#!/bin/dash
+# Filename:      run-screen
+# Purpose:       wrapper for screen to start with appropriate configuration
+# Authors:       grml-team (grml.org), (c) Michael Prokop <mika@grml.org>
+# Bug-Reports:   see http://grml.org/bugs/
+# License:       This file is licensed under the GPL v2.
+################################################################################
+
+# try to mitigate raceconditions from screen
+SCREENDIR_="/var/run/screen"
+mkdir -m 700 "${SCREENDIR_}/S-$USER" >/dev/null 2>&1
+
+# now run screen with config
+
+  if [ `id -u` = 0 ] ; then
+    exec screen -U -c /etc/grml/screenrc
+  elif [ -r "$HOME/.screenrc" ] ; then
+    exec screen -U -c "$HOME/.screenrc"
+  else
+    exec screen -U -c /etc/grml/screenrc_generic
+  fi
+
+## END OF FILE #################################################################
similarity index 99%
rename from usr_bin/zsh-login
rename to usr_share/run-welcome
index e32a17a..3d5dc34 100755 (executable)
@@ -1,5 +1,5 @@
 #!/bin/bash
-# Filename:      zsh-login
+# Filename:      run-welcome
 # Purpose:       customized zsh login welcome screen for use at grml
 # Authors:       grml-team (grml.org), (c) Michael Prokop <mika@grml.org>
 # Bug-Reports:   see http://grml.org/bugs/