#!/usr/bin/perl
#
# ICQ99b-2000b -> KXicq2 contact list converter
#
# This program was written for and tested on 
# KXicq2 0.7.6 and 2000b database 
# 
# (c)2002 Patrik Westerlund <patves-7@sm.luth.se>
# This program is released under the terms of the GPL.
#
# Thanks to Erwin Aitenbichler I've borrowed lots of code from
# his licq.winconverter
#

$path=(getpwuid($<))[7]."/.kde/share/apps/kxicq2/";
$fnUsers=$path."contacts.kxicq";
$verbose=1;
$|=1;

@fieldNames=("UIN","MyDefinedHandle","NickName","FirstName","LastName","PrimaryEmail");
@values=();

foreach $arg (@ARGV)
 {
  if ($arg eq "-q")
   { $verbose=0; }
  elsif ($arg eq "-v")
   { $verbose=2; }
  else
   { $fn=$arg; }
 }

if (!defined($fn))
 {
  print STDERR "\nsyntax: KXicq2.winconvert99b-20002 [options] <your_uin>.dat\n";
  print STDERR "Extracts all UINs out of an ICQ99b-2000b database\n";
  print STDERR "and OVERWRITES ~/.kde/share/apps/kxicq2/contacts.kxicq\n";
  print STDERR "\nThe .dat-file is usually located in: <your_win_drive>/Program Files/icq/2000b/\n";
  print STDERR "\noptions:\n";
  print STDERR "   -v   verbose\n";
  print STDERR "\n";
  exit 0;
 }


# get owner uin
# 
# NOT IMPLEMENTED will add yourself to list now ;) 
#

# import users

$count=0;
open(OUTFH, ">$fnUsers") || die "can't open '$fnUsers' for writing.\nMissing directory ? try starting kxicq and close it again then run the script.\n";
readFile($fn);

# Add Deafult and group info
print OUTFH "[Default]\nContacts=";

@list=sort {$a <=> $b} (keys %uins);
$i=1;
foreach $key (@list)
 {
     print OUTFH "$key,";
 }
print OUTFH "Count=$count\n";
print OUTFH "Group Id Count=0\n";
print OUTFH "Count=$count\n\n";
print OUTFH "[Groups]\n";
print OUTFH "Default Open=true\n";
print OUTFH "Wait Authorization Open=true\n";
close(OUTFH);
 
print "$count users add.\n" if $verbose>=1;

print "NOTE: This script doesn't support all user information fields.\n";

sub readFile()
 {
  my $fn=shift;
  open(INFH, "<$fn") || die "can't open file '$fn'\n";
  binmode INFH;    # for M$...
  $key="";
  $pos=0;
  print "reading" if $verbose==1;
  nextChar();
  while (nextPair())
   {
    if ($field==0)
     {
      if ($values[0]!=$own_uin && ($values[1] || $values[2]))
       {
        if (!$uins{$values[0]})
         {
          $uins{$values[0]}=1;
          $count++;
         }
        # write to file
        
	if ($verbose>=2)
	{
	    print "uin          : $values[0]\n";
	    print "display name : $values[1]\n";
	    print "nick name    : $values[2]\n";
	    print "first name   : $values[3]\n";
	    print "last name    : $values[4]\n";
	    print "email        : $values[5]\n\n";
	}

	my $fnUIN=$pathUsers.$values[0].".uin";
	if (!-f $fnUIN)
	{
	    print OUTFH "[Contact $values[0]]\n";
	    print OUTFH "Authorized=true\n";
	    print OUTFH "Nick=$values[2]\n";
	    print OUTFH "UIN=$values[0]\n\n";
	}

	# end of writing file
       }
      @values=();
     }
   }
  close(INFH);
  print "\n" if $verbose==1;
 }

sub nextPair()
 {
  do
   {
    nextKey();
    return 0 if (eof(INFH));
   }
  while (!$key);
  if ($c eq "k")
   {
    nextChar();
    readString();
   }
  elsif ($c eq "i")
   {
    read(INFH, $buffer, 4);
    $value=unpack("V", $buffer);
    nextChar();
   }
  $values[$field]=$value;
  return 1;
 }

sub nextKey()
 {
  while (ord($c)!=0) { nextChar(); }
  nextChar();
  my $s="";
  while (ord($c)!=0)
   {
    $s.=$c;
    nextChar();
   }
  for ($i=0; $i<=$#fieldNames; $i++)
   {
    if ($fieldNames[$i] eq $s)
     {
      nextChar();  # type
      $key=$s;
      $field=$i;
      return 1;
     }
   }
  $key="";
  return 0;
 }

sub nextChar()
 {
  $c=getc(INFH);
  print "." if ($verbose==1 && $pos%10000==0);
  $pos++;
 }

sub readString()
 {
  $value="";
  my $len=ord($c);
  nextChar();
  return 0 if $c!=0;
  nextChar();
  return 1 if ($len==0);
  my $i;
  for ($i=0; $i<$len-1; $i++)
   {
    return 0 if (ord($c)==0);
    $value.=$c;
    nextChar();
   }
  return 0 if $c!=0;
  return 1;
 }