#!/usr/bin/perl


print "Updating opensc.conf to fit CERES smart card...\n";

# Looks for opensc.conf
$openscconf=&lookforopenscconf;
if ($openscconf == -1) {
  print "Could not be able to find out the location of opensc.conf. Using a preconfigured file.\n";
  $openscconf="/etc/opensc/opensc.conf";
  system("cp", "/usr/share/opensc-ceres/opensc.conf.ceres", $openscconf);
  goto configure_startup;
}

$openscconfceres=$openscconf.".ceres";
$previousopenscconf=$openscconf.".bak.ceres";

# If a default opensc.conf file is found we make a direct replace
if (`diff $openscconf /usr/share/opensc-ceres/opensc.conf.default` == 0  ){
  print "A default opensc.conf file has been detected. Replacing it with a preconfigured one\n";
  system("cp", "/usr/share/opensc-ceres/opensc.conf.ceres", $openscconf);
  system("cp", "/usr/share/opensc-ceres/opensc.conf.default", $previousopenscconf);
  goto configure_startup;
}

# Looks for libopensc-ceres.so
$libopensc=&lookforlibopensc;
if ($libopensc == -1){
	print "Couldn't find libopensc-ceres.so. Maybe opensc-ceres is not correctly installed?\n";
	exit(0);
}

# Looks for libpkcs15-ceres.so
$libpkcs15=&lookforlibpkcs15;
if ($libpkcs15 == -1){
	print "Couldn't find libpkcs15-ceres.so. Maybe opensc-ceres is not correctly installed?.\n";
	exit(0);
}

#Searchin for a CERES previous configuration, if we find one we suppose that is correct.
#This maybe innacurate, old opensc-ceres may interfere.




#At this point a configuration of a modified opensc.conf is needed

system("cp", $openscconf, $previousopenscconf);
system("cp", $openscconf, $openscconfceres);
open(OPENSC,$openscconf);
open(BUFFER,">".$openscconfceres);

    @filecontent=<OPENSC>;
    $i=0;
    while($i <= $#filecontent){
  
  	$content=$filecontent[$i];	


if ($content=~/\t\ \ reader_drivers = pcsc\;\n/){
	$content="";
}

    if ($content=~/\#\ reader_drivers\ \=\ openct, pcsc, ctapi/){
        print BUFFER $content;
	$firstline ="\t\ \ reader_drivers = pcsc\;\n";
         $content = $firstline;
    }
        if($content=~/\t\ \ card_drivers = ceres\;\n/)
    {
	$content="";
    }
    if($content=~/\tcard_driver\ ceres\ \{/)
    {
	while($filecontent[$i]!~"\}")
	{
	$i++;
	}
	$content="";
    }
    if($content=~/card_drivers\ \=\ internal\;/){
	$content="";
    }

    if ($content=~/\#\ card_drivers\ \=\ customcos/){
        print BUFFER $content;
        $firstline ="\t\ \ card_drivers = ceres\;";
	$secondline="\n\tcard_driver\ ceres\ \{\n";
	$thirdline="\t\t\#The\ location\ of\ the\ driver\ library\n";
	$fourthline="\t\tmodule\ \=\ $libopensc;\n";
	$fivethline="\t\}\n";
	print BUFFER $firstline;
	print BUFFER $secondline;
	print BUFFER $thirdline;
	print BUFFER $fourthline;
        print BUFFER $fivethline;

	$content="";
	}
  

 if ($content=~/Force\ using\ specific\ card\ driver/){
        
	$firstline = "\t\ card_drivers = internal\;\n";
	print BUFFER $firstline;
        print BUFFER $content;
	$content = "";

}

    if($content=~/emulate\ custom\ \{/){	
        print BUFFER $content;
        print BUFFER $filecontent[$i+1];
        print BUFFER $filecontent[$i+2];
  	print BUFFER $filecontent[$i+3];
	    
        $firstline= 	"\t\tpkcs15init\ ceres\ \{\n";
        $secondline= 	"\t\t\t\#\ The\ location\ of\ the\ driver\ library\n";
        $thirdline= 	"\t\t\tmodule\ \=\ $libpkcs15;\n";
        $fourthline=	"\t\t\}\n";
	  
        print BUFFER $firstline;
        print BUFFER $secondline;
        print BUFFER $thirdline;
        $content=$fourthline;
	   	
	} 

    if($content=~/max_send_size/){
	$content="\t max_send_size\=252\;\n\t max_recv_size=252\;\n";
	$i++;
    }
      print BUFFER $content;
      $i++;

  }
close(OPENSC);
close(BUFFER);

print "Creating a copy of the original opensc.conf...\n";
system("mv",$openscconf, $previousopenscconf);
system("mv",$openscconfceres, $openscconf);

print "File opensc.conf updated successfully!\n";


# Copy the profile to its directory

system("cp","/usr/share/opensc-ceres/ceres.profile","/usr/share/opensc/ceres.profile");


# Copy .purgeopenscconf
$purgeopenscceres = "/usr/share/opensc-ceres/purgeceres";
$purgeopensc = "/usr/share/opensc/.purgeceres";
system("mv", $purgeopenscceres, $purgeopensc);

#Copy eliminadefault
$eliminadefaultceres = "/usr/share/opensc-ceres/eliminadefaultceres";
$eliminadefaultopensc = "/usr/share/opensc/.eliminardefaultceres";
system("mv", $eliminadefaultceres , $eliminadefaultopensc);

configure_startup:

# CONFIGURE GNOME SESSION START-UP
$gnome_default_session="/usr/share/gnome/default.session";

if (-e $gnome_default_session) {

  open(GNOME,$gnome_default_session);
  @gnomecontent=<GNOME>;
  $i=0;
  $ceres_found=0;

  while($i <= $#gnomecontent && $ceres_found!=1) {

    $content=$gnomecontent[$i];

    if ($content=~/opensc-ceres/) {
      $ceres_found=1;
    }

    $i++;
  }

  close(GNOME);

  if($ceres_found==0){
    
    # creating a copy of the original gnome default.session file
    $gnome_ceres_session="/usr/share/opensc-ceres/ceres.session";
    $gnome_default_session_orig=$gnome_default_session.".bak.ceres";
  
    system("cp", $gnome_default_session, $gnome_default_session_orig);
  
    open(SESSION,$gnome_default_session);
    open(BUFFER,">".$gnome_ceres_session);

    @filecontent=<SESSION>;
    $i=0;
    $script_name="/usr/share/opensc-ceres/inst_gnome_pkcs11_cert.pl";
  
    while($i <= $#filecontent) {
        $content=$filecontent[$i];

        if($content=~/num_clients=/){
            if ($content=~ m/(\d+)/) {
                $total_apps=$1;
                $actual_app=$1;
                $total_apps++;
	            $content="num_clients=".$total_apps."\n";
            }
        }
        
        print BUFFER $content;
        $i++;
    }
  
    close(CERES_SESSION);
    close(BUFFER);

    open(BUFFER,">>".$gnome_ceres_session);

    #Add new app info
    $firstline= 	$actual_app.",id=default".$actual_app."\n";
    $secondline= 	$actual_app.",Priority=50\n";
    $thirdline= 	$actual_app.",RestartCommand=".$script_name." --sm-client-id default".$actual_app."\n";

    print BUFFER $firstline;
    print BUFFER $secondline;
    print BUFFER $thirdline;

    close(BUFFER);
  
    # copying the ceres session file to the default.session one
    system("mv", $gnome_ceres_session, $gnome_default_session);
  }
}

# CONFIGURE KDE SESSION START-UP
$kde_ceres_session="/usr/share/apps/kconf_update/";

if (-e $kde_ceres_session) {
  # copying scripts to automatically run it once for each user
  system("cp", "/usr/share/opensc-ceres/kceres.upd", "/usr/share/opensc-ceres/inst_kde_pkcs11_cert.pl", $kde_ceres_session);
}


# calls ldconfig
system("ldconfig");


sub lookforopenscconf{
	if (-e "/etc/opensc.conf") {
		return "/etc/opensc.conf";
	} 
	elsif (-e "/etc/opensc/opensc.conf") {
		return "/etc/opensc/opensc.conf"
	}
	elsif (-e  "/usr/local/etc/opensc.conf") {
		return "/usr/local/etc/opensc.conf";
	} 
	else {
		return -1;
	}
}

sub lookforlibopensc {
 	if (-e "/usr/lib/libopensc-ceres.so") {
		return "/usr/lib/libopensc-ceres.so";
	} 
	elsif (-e  "/usr/local/lib/libopensc-ceres.so") {
		return "/usr/local/lib/libopensc-ceres.so";
 	}
 	else {
 		return -1;
 	}
}

sub lookforlibpkcs15 {
	if (-e "/usr/lib/libpkcs15init-ceres.so") {
		return "/usr/lib/libpkcs15init-ceres.so";
	}
	elsif (-e  "/usr/local/lib/libpkcs15init-ceres.so") {
		return "/usr/local/lib/libpkcs15init-ceres.so";
	} 
	else {
		return -1;
	}
}
