#!/afs/athena/contrib/perl/perl

require 'sys/socket.ph';

($them,$port) = @ARGV;
open(WGFILE, $ENV{'WGFILE'});
chop($port = (<WGFILE>));
close(WGFILE);
print("port is -$port-\n");

$them = 'localhost' unless $them;

$SIG{'INT'} = 'dokill';
sub dokill {
    kill 9,$child if $child;
}

$sockaddr = 'S n a4 x8';

chop($hostname = `hostname`);

($name,$aliases,$proto) = getprotobyname('udp');
($name,$aliases,$port) = getservbyname($port,'udp')
    unless $port =~ /^\d+$/;;
($name,$aliases,$type,$len,$thisaddr) =
	gethostbyname($hostname);
($name,$aliases,$type,$len,$thataddr) = gethostbyname($them);

$this = pack($sockaddr, &AF_INET, 0, $thisaddr);
$that = pack($sockaddr, &AF_INET, $port, $thataddr);

# Make the socket filehandle.

if (socket(S, &AF_INET, &SOCK_DGRAM, $proto)) { 
    print "socket ok\n";
}
else {
    die $!;
}

# Give the socket an address.

if (bind(S, $this)) {
    print "bind ok\n";
}
else {
    die $!;
}

# Call up the server.

if (connect(S,$that)) {
    print "connect ok\n";
}
else {
    die $!;
}

# Set socket to be command buffered.

select(S); $| = 1; select(STDOUT);

# Avoid deadlock by forking.

if($child = fork) {
    print S &zpacket(0,"message", "personal", "", "mkgray.test", "mkgray", "message from \$sender", "Foosig", "Message here");

    sleep 3;
    do dokill();
}
else {
    while(<S>) {
	print("Received from zwgc: $_");
    }
}
sub zascii {
	local($retval,$data) = ("",$_[0]);
	while (length($data)>=4) {
		$retval .= " " if ($retval);
		($c1,$c2,$c3,$c4,$data) = unpack("C4a*",$data);
		$retval .= sprintf("0x%02X%02X%02X%02X",$c1,$c2,$c3,$c4);
	}

	if ($data) {
		$retval .= " " if ($retval);
		$retval .= "0x";
		while ($data) {
			($c1,$data) = unpack("Ca*",$data);
			$retval .= sprintf("%02X",$c1);
		}
	}

	return($retval);
}

sub zlong {
	return(&zascii(pack("N",$_[0]))."\0");
}
sub zpacket {
	local($uid, $class, $inst, $opcode, $sender, $recip, $default, $zsig, 
	      $msg)
		= @_;
	local($packet);

	if (! $uid) {
		$localaddr = ((gethostbyname(&thechop(`hostname`)))[4])
				if (! $localaddr);
		$uidinc = 0 if ($oldtime != time);
		$uidinc++;
		$uid = pack("a4 N N",$localaddr,$oldtime=time,$uidinc);
	}

	$packet .= "ZEPH0.2\0";
	$packet .= &zlong(17);
	$packet .= &zlong(0);			# UNSAFE
	$packet .= &zascii($uid)."\0";
	$packet .= &zascii(pack("n",$port))."\0";	# no response port
	$packet .= &zlong(2);			# no auth
	$packet .= &zlong(0);			# authlen = 0
	$packet .= "\0";			# no authdata
	$packet .= $class."\0";
	$packet .= $inst."\0";
	$packet .= $opcode."\0";
	$packet .= $sender."\0";
	$packet .= $recip."\0";
	$packet .= $default."\0";
	$packet .= &zlong(0);			# no checksum
	$packet .= "\0";			# no fragmentation
	$packet .= &zascii($uid)."\0";
	$packet .= "$zsig\0".$msg;
}

sub thechop {
	local($foo) = $_[0];
	chop($foo);
	return($foo);
}
