Kerberized tmux.
authorIain Patterson <me@iain.cx>
Wed, 3 Nov 2010 15:29:22 +0000 (15:29 +0000)
committerIain Patterson <me@iain.cx>
Fri, 26 Nov 2010 15:39:41 +0000 (15:39 +0000)
Added ktmux - Kerberized tmux, launching ktmux_helper to keep tickets
updated in the background.

opt/bin/ktmux [new file with mode: 0755]
opt/bin/ktmux_helper [new file with mode: 0755]

diff --git a/opt/bin/ktmux b/opt/bin/ktmux
new file mode 100755 (executable)
index 0000000..d0c063c
--- /dev/null
@@ -0,0 +1,14 @@
+#!/bin/bash
+
+tmux=tmux
+tmux_opts=
+session_opts=
+while getopts ":T:n:s:t:" opt; do
+  case $opt in
+    T) tmux="$OPTARG";;
+    n|s|t) session_opts="$session_opts -$opt $OPTARG";;
+  esac
+done
+shift $((OPTIND-1))
+
+exec $tmux ${tmux_opts## } new-session ${session_opts## } -d ';' attach ';' run-shell ktmux_helper
diff --git a/opt/bin/ktmux_helper b/opt/bin/ktmux_helper
new file mode 100755 (executable)
index 0000000..e62b4a5
--- /dev/null
@@ -0,0 +1,86 @@
+#!/usr/bin/perl
+#
+# ktmux_helper: Run krenew in the background for tmux.
+# Notes: Doesn't handle multiple sessions properly.
+#
+
+use FindBin;
+use POSIX ":sys_wait_h";
+
+my $PROG = $FindBin::Script;
+
+# Ensure tmux is our parent and find its PID.
+my $tmux_pid = &get_tmux_pid;
+unless ($tmux_pid) {
+  print STDERR "$PROG: Not a child of tmux!\n";
+  exit 100;
+}
+
+# Ensure there isn't already a helper running for this tmux.
+my $tmux_helper = &get_tmux_helper;
+exit 0 if $tmux_helper;
+
+my $exitasap = 0;
+my $pid = 0;
+
+$SIG{INT} = \&cleanup;
+$SIG{QUIT} = \&cleanup;
+$SIG{TERM} = \&cleanup;
+
+LOOP: while (&ping_tmux) {
+  $pid = fork;
+  die "$PROG: Can't fork: $!\n" unless defined $pid;
+
+  if ($pid) {
+    while (&ping_tmux) {
+      my $exited = waitpid $pid, WNOHANG;
+      goto LOOP if $exited == $pid || $exited < 0;
+      sleep 1;
+    }
+
+    # tmux is dead so kill krenew.
+    kill 3, $pid;
+    waitpid $pid, 0;
+    exit 0;
+  }
+  else {
+    exec "krenew", "-K", "60";
+    print "$PROG: Can't run krenew: $!\n";
+    exit 111;
+  }
+}
+
+sub get_tmux_pid {
+  my $pid = getppid;
+  my $cmd = `/bin/ps -o args= -p $pid`;
+  return $pid if $cmd =~ /\btmux\b/;
+  return undef;
+}
+
+sub get_tmux_helper {
+  my $pid = undef;
+  if (open IN, "pgrep -x -P $tmux_pid $PROG | ") {
+    while (<IN>) {
+      chomp;
+      s/[^\d]//g;
+      next if $_ == $$;
+      $pid = $_;
+      last;
+    }
+    close IN;
+  }
+  return $pid;
+}
+
+sub ping_tmux {
+  return kill 0, $tmux_pid;
+}
+
+sub cleanup {
+  unless ($exitasap) {
+    $exitasap = 1;
+    kill $pid;
+    waitpid $pid, WNOHANG;
+    exit 0;
+  }
+}