#!/usr/bin/perl
##############################################################################
=pod

=head1 NAME

 xchat server list conversion script 
 author Bruno BÖTTCHER <bboett@dont send me spam adlp.org>

 type perldoc thisfile to get the formatted docu
 
=head1 COPYRIGHT and LICENCE

Copyright (c) 2003 Bruno Boettcher
 
xchatRecode.pl is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; version 2
of the License.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

=head1 INSTRUCTIONS

invoque this script and redirect its ouput to some file, e.g. :

xchatRecode.pl >~/.xchat2/servlist_.conf (make sure you did understand very well the licence!!!)

=over

=head2 Commented xchat2 entry

- ----beginning of servlist_.conf----

  v=2.0.2    ## The very first line shows the version of X-Chat

  N=Network1 name   << Name for a network (a group of servers)
  I=Nickname    << Nickname (if not using global settings)
  U=username    << Username (If not using global settings)
  R=Real Name    << Real name (If not using global settings)
  P=network_password
      ^^ Network password (on bahamut, it works as NickServ password ;) )
  J=#Chan1,#Chan2,#Chan3,#Chan4,#Chan5 ,Chan2Key,,Chan4Key
      ^^ joined channels and their keys 
  E=UTF-8    << Encoding (if not using system default)
  C=    << Connect command
  F=63    << Server flags
  D=0    << Default server number
  S=server0/6668
  S=server1/6668
  S=server2/6668
  S=server3/6668
  S=server4/6668

  N=Network2 name   << Name for a network (a group of servers)
  I=Nickname    << Nickname (if not using global settings)
  U=username    << Username (If not using global settings)
  R=Real Name    << Real name (If not using global settings)
  P=network_password
      ^^ Network password (on bahamut, it works as NickServ password ;) )
  J=#Chan1,#Chan2,#Chan3,#Chan4,#Chan5 ,Chan2Key,,Chan4Key
      ^^ joined channels and their keys 
  E=UTF-8    << Encoding (if not using system default)
  C=    << Connect command
  F=27    << Server flags
  D=0    << Default server number
  S=server0/6668
  S=server1/6668
  S=server2/6668
  S=server3/6668
  S=server4/6668

- ----end of servlist_.conf

=cut

##############################################################################
use strict; 

use Data::Dumper;

my $list = {};
$list->{"anonymous"} = {};

my @groupStack;
my $actGroup = $list->{"anonymous"};
my $actServer  ;

open(OLDLIST, $ENV{HOME}."/.xchat/serverlist.conf") || die("couldn't open old conf list\n");

#go forth to first block
my $skipping = 1;
while(<OLDLIST>)
{
  chomp;
  if(/=/)
  {
    my($key,$server) = split(/ = /);
    if($key =~ /^servername/)
    {
      #print("found server: $server\n");
      if($server eq "SUB")
      {
	my($dummy,$group);
	while(<OLDLIST>)
	{
	  chomp;
	  ($dummy,$group) = split(/ = /);
	  last if(/^comment/);
	}# while(<OLDLIST>)
	#print("NEW group named: $group\n");
	$list->{$group} = {} if(!($list->{$group}));
	push(@groupStack,$actGroup);
	$actGroup = $list->{$group};
	$actServer  = undef;
      }# if($server eq "SUB")
      elsif($server eq "ENDSUB")
      {
	while(<OLDLIST>)
	{
	  last if(/^\s*$/);
	}# while(<OLDLIST>)
	push(@groupStack,$actGroup);
	$actGroup = pop(@groupStack);
	$actServer  = undef;
      }# if($server eq "SUB")
      else
      {
	#new server conf
	#$actGroup->{$server} = {} if(!($actGroup->{$server}));
	#$actServer  = $actGroup->{$server};
	$actServer  = { "server" => $server };
      }#else
    }#if($key =~ /^servername/)
    else
    {
#       normal entry
      if($actServer)
      {
	$actServer->{$key} = $server if($server);
      }# if($actServer)
    }# else
  }# if(/=/)
  else
  {
    #we have an end of line....
    if($actServer)
    {
      my $name;
      if($actServer->{"comment"})
      {
	$name = $actServer->{"comment"};
      }
      else
      {
	$name = $actServer->{"server"};
      }

      #check if we are compatible....
      my @randomNames =keys(%$actGroup);
      my $randomName =shift @randomNames;
      my $randomServer = $actGroup->{$randomName};
      if($randomServer)
      {
	my $channels = $actServer->{"channel"};
	if($randomServer->{"channel"} =~ /$channels/)
	{
# 	  #ok we have concordance....
	  $actGroup->{$name} = $actServer;
	}# if($randomServer->{"channel"} =~ /$channels/)
	else
	{
	  #no concordance....
	  $list->{$name} = $actServer;
	}#else
      }# if($randomServer)
      else
      {
	#no entry in this group....
	$actGroup->{$name} = $actServer;
      }#else
      #$actServer  = $actGroup->{$server};
      $actServer  = undef;
    }# if($actServer)
  }# else
}#while(<OLDLIST>)
#print "Dumpoing them all:".Dumper($list)."\n";
#print "Dumpoing groups:".Dumper(keys(%$list))."\n";
foreach my $group (keys(%$list))
{
  my $actEntry = $list->{$group};
  if($actEntry->{"server"})
  {
    print dumpServer($actEntry,$group)."\n";
  }# if($actEntry->{"server"})
  else
  {
    #print ("type = group\n"); 
    #fetch the first server for the settings and fetch only the server from the rest....
    my @names = keys(%$actEntry);
    my $name = shift(@names);
    my $actServer =  $actEntry->{$name};
    print(dumpServer($actServer,$group));
    foreach $name (@names)
    {
      $actServer = $actEntry->{$name};
      print("S=".$actServer->{"server"}."\n");
    }# foreach my $name (keys($actEntry)
	print("\n");
	}# else
	}#foreach my $group (keys($list)



	  sub dumpServer
	  {
	  my($actEntry,$group) = @_;
#print ("type = server\n"); 
	  my $msg = "N=$group\n";
	  $msg .= "I=".$actEntry->{"nick"}."\n" if($actEntry->{"nick"});
	  $msg .= "P=".$actEntry->{"password"}."\n" if($actEntry->{"password"});
	  $msg .= "J=".$actEntry->{"channel"}."\n" if($actEntry->{"channel"});
	  #TODO don't know old flags sceme....
	  #new sceme:
	  #F field is a sum of numbers, which are (as i just found out):
	  #1 - Try all servers in a network
	  #2 - Use global settings for nickname, username, realname
	  #4 - Use SSL
	  #8 - Autoconnect to a network
	  #16 - Use proxy (if proxy is set)
	  #32 - Accept invalid SSL certificates.
	  #0 - none of these

	  if($actEntry->{"flags"} != 0)
	  {
	    my $mode = 9; 
	    $mode += 2 if(!($actEntry->{"nick"}));
	    $msg .= "F=$mode\n"
	  }# if($actEntry->{"flags"} != 0)
	  if($actEntry->{"eom_cmd"})
	  {
	    $actEntry->{"eom_cmd"} =~ s/^\///;
	    $msg .= "C=".$actEntry->{"eom_cmd"}."\n" 
	  }#if($actEntry->{"eom_cmd"})
	  $msg .= "S=".$actEntry->{"server"};
	  $msg .= "/".$actEntry->{"port"} if($actEntry->{"port"});
	  $msg .= "\n";
	  return $msg;
	  }#sub dumpServer

__END__

=back

=head1 AUTHOR

Bruno Böttcher <bboett at adlp.org>

=head1 THANKS

big thanks to Rimas Kudelis <rq@please dont send him spam ursus.mif.vu.lt>
for sending me the format of the xchat2 server list file!

=cut
