#
# Copyright C 2004 Sun Microsystems, Inc.
# All rights reserved. Use is subject to license terms.
#
# 
# Sun, Sun Microsystems, and the Sun logo are trademarks or registered
# trademarks of Sun Microsystems, Inc. in the United States and other
# countries.
# 
# Federal Acquisitions: Commercial Software--Government Users Subject to
# Standard License Terms and Conditions
#

#
# $Revision: 1.26.2.6 $ $Date: 2004/03/19 09:04:09 $
#

namespace eval dps52ins {

    proc appendMagnus { xName } {
	upvar $xName x

	set iName [file join $x(root) bin/dps/install/magnus.conf] 

	if [catch {open $iName r} iFile] {
	} else {
	    set magnus [list]

	    while {[gets $iFile line] >= 0} {
		lappend magnus $line
	    }

	    close $iFile

	    set oName [file join $x(root) admin-serv/config/magnus.conf]

	    if [catch {open $oName a+} oFile] {
	    } else {
		foreach i $magnus {
		    puts $oFile $i
		}
		close $oFile
	    }
	}
    }

    proc convert { xName } {
	upvar $xName x
	
	fetchSie x
	
	set rc [createInstance x]

	if {$rc} {
	} else {
	    set ldapadd [file join $x(root) shared bin [cmd ldapadd]]
	    
	    set ldapaddFound [file exists $ldapadd] 
	    
	    if {$ldapaddFound} {
	    } else {
		set ldapmodify [sharedBin x ldapmodify]
		file copy $ldapmodify $ldapadd
	    }
	    
	    set cmd [list \
		    [file join $x(java.home) [cmd java]] \
		    -cp [file join $x(root) java jars dps522.jar][javaSeperator][file join $x(root) java ldapjdk.jar] \
		    com.iplanet.idar.util.MigrateConfig2 \
		    -h $x(cdsHost) \
		    -p $x(cdsPort) \
		    -D $x(user) \
		    -w $x(password) \
		    -C $x(sie) \
		    -E [file dirname $ldapadd] \
		    -L [file join $x(instanceRoot) etc] \
		    -B [file join $x(instanceRoot) etc backup.ldif] \
		    -v \
		    ]
	    
	    set rc [execProgram x $cmd]
	    
	    if {$ldapaddFound} {
	    } else {
		file delete $ldapadd
	    }

	    restartAdmin x
	}

	return $rc
    }

    proc createInstance { xName } {
	upvar $xName x
	
	mkdir $x(instanceRoot) 0755
	mkdir $x(instanceRoot)/etc 0700
	mkdir $x(instanceRoot)/logs 0700
	mkdir $x(instanceRoot)/tmp 0755
	
	dpsAsk x
	
	ldapModify x [file join $x(root) bin dps install schema 50ns-dar-prime.ldif]

	ldapModify x [file join $x(root) bin dps install schema 52ns-dps.ldif]

	set cmd [list \
		$x(tclsh) \
		[file join $x(root) bin dps install script dpsInitLdif.tcl] \
		-root $x(root) \
		-currentInstallDirectory $x(currentInstallDirectory) \
		-listen $x(dpsPort) \
		-host $x(fullHostname) \
		-domain $x(domain) \
		-security $x(security) \
		-bind_dn $x(user) \
		-bind_pw $x(password) \
		-build $x(build) \
		-url ldap://$x(cdsHost):$x(cdsPort) \
		-revision $x(revision) \
		-repositoryhost $x(cdsHost) \
		-repositoryport $x(cdsPort) \
		-hostname $x(hostname) \
		-instance $x(instance) \
		-config $x(suffix) \
		]
	
	set rc [execProgram x $cmd]
	
	foreach i [list Nickname] {
	    if { $rc } {
	    } else {
		set rc [setupUpdateLdif x [file join $x(instanceRoot) etc "dps$i.ldif"]]
	    }
	}

	set iName [file join $x(root) admin-serv config adm.conf]
	
	set iFile [open $iName r]
	
	set server "Server Group"
	
	while {[gets $iFile line] >= 0} {
	    if [regexp -nocase "^isie\:" $line] {
		regexp -nocase "(\[^,\]+),(\[^,\]+)," $line a b c
		regexp -nocase "(\[^=\]+)=(.+)" $c d e server
	    }
	}
	
	close $iFile
	
	set oFile [open [file join $x(instanceRoot) etc tailor.txt] w 0600]

	puts $oFile "Begin"
	puts $oFile "configuration_url: ldap://$x(cdsHost):$x(cdsPort)/cn=$x(instance), cn=Sun One Directory Proxy Server, cn=$server, cn=$x(fullHostname), ou=$x(domain), o=NetscapeRoot"
	puts $oFile "configuration_bind_dn: $x(user)"
#	puts $oFile "configuration_bind_pw: $x(password)"
	puts $oFile "configuration_bind_pw: [scramble $x(password)]"
	puts $oFile "End"

	close $oFile

	return $rc
    }

    proc dpsAsk { xName } {
	upvar $xName x
	
	set cwd [pwd]
	
	cd [file join $x(root) bin dps server bin]
	
	if [catch {glob dpsAsk*.txt} result] {
	} else {
	    foreach i $result {
		if [catch {file copy $i [file join $x(instanceRoot)]} result] {
		    puts stderr $result
		}
	    }
	}
	
	cd $cwd
    }

    proc fetchSie { xName } {
	upvar $xName x
	
	set iName [file join $x(root) admin-serv config adm.conf]
	
	set iFile [open $iName r]

	set isie ""

	while {[gets $iFile line] >= 0} {
	    if [regexp -nocase "^isie\:" $line] {
		regexp -nocase "^isie\:\[ \t\]*(.+)" $line a isie
	    }
	}
	
	close $iFile
	
	if [string length $isie] {
	    set i [string first "," $isie]
	    if [expr $i > 0] {
		set j [expr [string equal [string range $isie $i [expr $i + 1]] ", "] + 1 + $i]
		set x(sie) "cn=idar-$x(hostname), cn=iPlanet Directory Access Router, [string range $isie $j end]"
	    } else {
		error "isie's form not as expected."
	    }
	} else {
	    error "Could not resolve isie."
	}
    }
    
    proc main { xName } {
	upvar $xName x
	
	if [file exist $x(instanceRoot)] {
	    set rc [patch x]
	} else {
	    set rc [ootb x]
	}
	return $rc
    }
    
    proc ootb { xName } {
	upvar $xName x

	catch {appendMagnus x} result
	
	execProgram x [list \
		[file join $x(java.home) bin [cmd java]] \
		-cp [file join $x(root) setup dps dps52Setup.jar][javaSeperator][file join $x(root) java ldapjdk.jar][javaSeperator]. \
		com.sun.dps.ldapUtil \
		-cdshost $x(cdsHost) \
		-cdsport $x(cdsPort) \
		-domain $x(domain) \
		-killidarplugin \
		-password $x(password) \
		-user $x(user) \
		]
	
	set rc [createInstance x]

	ldapModify x [file join $x(instanceRoot) etc dpsISIE.ldif]
	
	foreach i [list DefaultConfiguration Base Task TopologyPlugin] {
	    if { $rc } {
	    } else {
		set rc [setupReplaceLdif x [file join $x(instanceRoot) etc "dps$i.ldif"]]
	    }
	}

	restartAdmin x
	
	return $rc
    }
    
    proc patch { xName } {
	upvar $xName x

	return 0
    }

    proc scramble {string} {
	

	set i 0
	
	foreach char   {A B C D E F G H I J K L M N O P Q R S T U V W X Y Z a b c d e f g h\
	i j k l m n o p q r s t u v w x y z 0 1 2 3 4 5 6 7 8 9 + /} {
		set theArray($i) $char
		incr i
	}

	set theResult "{}"
	set theState 0

	foreach {c} [split $string {}] {

	scan $c %c x

	switch [incr theState] {
	    1 {	append theResult $theArray([expr { ($x >>2) & 0x3f}]) }
	    2 { append theResult $theArray([expr { (($previous << 4) & 0x30) | (($x >> 4) & 0xf)}]) }
	    3 { append theResult $theArray([expr {(($previous << 2) & 0x3c) | (($x >> 6) & 0x3)}])
		append theResult $theArray([expr {($x & 0x3f)}])
		set theState 0}
	}
	set previous $x
        }

	# don't forget trailing bytes if any 

    	set x 0
    	switch $theState {
		0 {}
		1 { append theResult $theArray([expr {(($previous << 4) & 0x30)}])  == }
		2 { append theResult $theArray([expr {(($previous << 2) & 0x3c)}])  =  }
    	}
    	return $theResult
    
    }

    proc unscramble {string} {

	if [string match "{}*" $string] {

	set i 0
	foreach char   {A B C D E F G H I J K L M N O P Q R S T U V W X Y Z a b c d e f g h\
	i j k l m n o p q r s t u v w x y z 0 1 2 3 4 5 6 7 8 9 + /} {
		set theArray($char) $i
		incr i
	}

	set theGroup 0
	set Bits 18
	foreach char [split [string trim $string "{}"] {}] {
		if {[string compare $char "="]} {
	    		set theBits $theArray($char)
	    		set theGroup [expr {$theGroup | ($theBits << $Bits)}]
	    		if {[incr Bits -6] < 0} {
				scan [format %06x $theGroup] %2x%2x%2x t1 t2 t3
				append theResult [format %c%c%c $t1 $t2 $t3]
				set theGroup 0
				set Bits 18
	    		}
		} else {
	    		scan [format %04x $theGroup] %2x%2x t1 t2 
	    		if {$Bits == 6} {
				append theResult [format %c $t1]
	    		} elseif {$Bits == 0} {
				append theResult [format %c%c $t1 $t2]
	    		}
	    		break
		}
	}

	} else {
		set theResult $string
	}

	return $theResult
	}
}
