#!/usr/bin/perl

# /usr/local/src/sitebuilder3/src/utils/vps_remove.pl --service_ve_ip=10.58.21.1 
#													  --vps_id=132
#													  --workdir=/var/www/test/andrey 
#													  --file=check.php
# output packet
#<packet time="2006-09-28T09:12:37+0000" priority="0" version="3.0.0">
#<origin>filem</origin>
#<target>vzclient50</target>
#<dst>
#<director>servd</director>
#</dst>
#<data>
#<filem>
#	<ok/>
#</filem>
#</data>
#<src>
#<director>opd</director>
#</src>
#</packet>


use IO::Handle;

my $arg = join(' ',@ARGV);

my @opts 				= map { [ split(/\=/,$_) ] } @ARGV;
my $ve_id 				= undef;
my $sve_ip 				= undef;
my $wdir 				= undef;
my $path_remove_file	= undef;

foreach my $opt (@opts) {
	$ve_id 	= $opt->[1] if $opt->[0] eq '--vps_id';
	$sve_ip = $opt->[1] if $opt->[0] eq '--service_ve_ip';
	$wdir = $opt->[1] if $opt->[0] 	 eq '--workdir';
	$file = $opt->[1] if $opt->[0] eq '--file';
}

my $packet_remove = <<PACKET;
<packet version="3.0.0">
	<target>filem</target>
	<data>
		<filem>
			<remove>
				<veid>%%VEID%%</veid>
				<cwd>%%WDIR%%</cwd>
				<path>%%FILE%%</path>
			</remove>
		</filem>
	</data>
</packet>
PACKET

#Remove file
sub remove_file () {
	my $result = 0;
	my ($rd, $wr, $pid) = &vza_ssh_connect(
		"/usr/bin/ssh",
		"-oPasswordAuthentication=no",
		"-oProtocol=1",
		"-lvzagent0",
		"-T",
		"-oStrictHostKeyChecking=no",
		"-oConnectionAttempts=1",
		$sve_ip);
	my $resp = &recv_packet($rd);
	$result = &check_ok($resp);
	if ($result) {
		my $chdir = &encode_base64($wdir);
		my $remove_file = &encode_base64($file);
		$packet_remove =~ s/\%\%VEID\%\%/$ve_id/g;
		$packet_remove =~ s/\%\%WDIR\%\%/$chdir/g;
		$packet_remove =~ s/\%\%FILE\%\%/$remove_file/g;
		&send_packet($wr,$packet_remove);
		$resp = &recv_packet($rd);
		print $resp;
	}
}

sub check_ok {
	my $resp = shift;
	return ($resp && $resp =~ /\<ok\/\>/m) ? 1 : 0;
}

sub vza_ssh_connect {
	my ($rd, $wr);
	my $rd_ssh = undef; my $wr_ssh = undef;

	&exit_error("failed to connect to VZAgent")
	    unless (pipe ($rd, $wr_ssh) && pipe ($rd_ssh, $wr));

	$rd->autoflush(1);
	$wr->autoflush(1);
	$rd_ssh->autoflush(1);
	$wr_ssh->autoflush(1);

	my $pid = fork();
	&exit_error("fork failed")
	    unless defined($pid);

	if (!$pid)
	{
		# Ssh channel
		close($rd); close($wr);

		close(STDOUT); open(STDOUT, ">&".fileno($wr_ssh));
		close(STDIN); open(STDIN, "<&".fileno($rd_ssh));

		exec(@_);
		exit(1);
	}

	# Main program
	close($wr_ssh);
	close($rd_ssh);
	return ($rd,$wr,$pid);
}

sub send_packet {
	my $wr = shift;
	my $packet = shift;
	# warn("Send:");
	# warn($packet);
	my $bytes = syswrite($wr,$packet."\0",length($packet)+1);
	return $bytes;
}

sub recv_packet {
	my $rd = shift;
	my $buf = undef;

	my $old_sep = $/;
	$/ = "\0";

	while(<$rd>) {
		$buf = $_;
		# warn("Rec:");
		# warn($buf);
		chomp($buf);
		length($buf) ? last : next;
	}
	$/ = $old_sep;
	return $buf;
}

sub encode_base64 {
	my ($str, $eol) = @_;
	use integer;
	return '' unless length($str);
	$eol = '' unless defined($eol);
	my $res = pack("u", $str);
	# Remove first character of each line, remove newlines
	$res =~ s|^.||mg;
	$res =~ s|\n||g;
	$res =~ tr|` -_|AA-Za-z0-9+/|;
	# fix padding at the end
	my $padding = (3 - length($str) % 3) % 3;
	$res =~ s/.{$padding}$/'=' x $padding/e
		if $padding;
    if (length $eol) {
		$res =~ s/(.{1,76})/$1$eol/g;
    }
	return $res;
}

sub decode_base64 {
	my $str = shift;
	use integer;
	return '' unless length($str);
	## removing SAFENESS if it is
	if ($str =~ /[_\-]/){
		$str =~ tr/\_/\//;
		$str =~ tr/\-/\+/;
	}
	$str =~ tr|A-Za-z0-9+=/||cd;
	$str =~ s|=+$||;
	$str =~ tr|A-Za-z0-9+/| -_|;
	return '' unless length $str;
	my ($i, $l, $uustr);
	$l = length($str) - 60;
	for ($i = 0; $i <= $l; $i += 60) {
		$uustr .= "M".substr($str, $i, 60);
	}
	$str = substr($str, $i);
	# any leftover chars
	if ($str ne '') {
		$uustr .= chr(32 + length($str)*3/4).$str;
	}
	return unpack ("u", $uustr);
}

sub exit_error {
	my $error = shift;
	print "Error: $error\n";
	warn "vps_publish error: $error";
	exit(1);
}

remove_file();

#kill 9,$pid;
#waitpid($pid,0);
exit(0);